19136808282 3 сар өмнө
parent
commit
97c6f626e4

+ 113 - 0
.history/soul-app/src/app/drift-bottle/drift-bottle.component_20241227185338.ts

@@ -0,0 +1,113 @@
+import { Component, OnInit, OnDestroy, Renderer2, ElementRef, ViewChild } from '@angular/core';
+import { Router } from '@angular/router';
+import { IonicModule } from '@ionic/angular';
+import { openThrowDriftBottleModal } from '../throw-drift-bottle/throw-drift-bottle.component';
+import { ModalController } from '@ionic/angular/standalone';
+import { HttpClient } from '@angular/common/http';
+import { CloudObject, CloudQuery } from 'src/lib/ncloud';
+import { UserService } from 'src/app/user.service'; // 假设这是你的用户服务
+import { CommonModule } from '@angular/common'; // 导入 CommonModule
+
+@Component({
+  selector: 'app-drift-bottle',
+  templateUrl: './drift-bottle.component.html',
+  styleUrls: ['./drift-bottle.component.scss'],
+  standalone: true,
+  imports: [
+    IonicModule,
+    CommonModule, // 添加 CommonModule
+    // 其他导入项...
+  ]
+})
+export class DriftBottleComponent implements OnInit, OnDestroy {
+  alertHeader: string = '';
+  alertMessage: string = '';
+
+  @ViewChild('backgroundAudio', { static: false }) audioElement!: ElementRef<HTMLAudioElement>;
+
+  constructor(
+    private router: Router,
+    private modalCtrl: ModalController,
+    private http: HttpClient,
+    private renderer: Renderer2,
+    private userService: UserService // 注入用户服务
+  ) {}
+
+  ngOnInit() {
+    if (this.audioElement && this.audioElement.nativeElement) {
+      const audio = this.audioElement.nativeElement;
+      audio.loop = true;
+      audio.play().catch(error => {
+        console.error('Failed to play audio:', error);
+      });
+    } else {
+      console.warn('Audio element not found');
+    }
+  }
+
+  ngOnDestroy() {
+    if (this.audioElement && this.audioElement.nativeElement) {
+      const audio = this.audioElement.nativeElement;
+      audio.pause();
+      audio.currentTime = 0; // 重置音频时间
+      console.log('Audio element paused and reset');
+    } else {
+      console.warn('Audio element not found during destroy');
+    }
+    console.log('ngOnDestroy called');
+  }
+
+  throwDriftBottleModal() {
+    openThrowDriftBottleModal(this.modalCtrl);
+  }
+
+  catchDriftBottle() {
+    const query = new CloudQuery("DriftBottle");
+    query.equalTo("status", "drifting");
+
+    query.find().then((driftingBottles: any[]) => {
+      if (driftingBottles.length === 0) {
+        this.alertHeader = '失败';
+        this.alertMessage = '没捞到…';
+        return;
+      }
+
+      const randomIndex = Math.floor(Math.random() * driftingBottles.length);
+      const bottleToCatch = driftingBottles[randomIndex];
+
+      const username = this.userService.getUsername(); // 获取当前用户的用户名
+      if (!username) {
+        console.error('用户未登录或未找到用户名');
+        this.alertHeader = '错误';
+        this.alertMessage = '用户未登录,请先登录。';
+        return;
+      }
+
+      bottleToCatch.set("status", "caught");
+      bottleToCatch.set("catcher", username); // 设置打捞者
+      bottleToCatch.set("catchTime", new Date()); // 设置打捞时间
+
+      bottleToCatch.save().then(() => {
+        this.alertHeader = '成功';
+        this.alertMessage = '捞到啦!快去看看吧!';
+      }).catch((err: any) => {
+        console.error('更新漂流瓶状态时出错:', err);
+        this.alertHeader = '错误';
+        this.alertMessage = '发生错误,请重试。';
+      });
+    }).catch((err) => {
+      console.error('获取漂流瓶时出错:', err);
+      this.alertHeader = '错误';
+      this.alertMessage = '发生错误,请重试。';
+    });
+  }
+
+  dismissAlert() {
+    this.alertHeader = '';
+    this.alertMessage = '';
+  }
+
+  goMydriftbottle() {
+    this.router.navigate(['tabs/my-drift-bottle']);
+  }
+}

+ 100 - 0
.history/soul-app/src/app/drift-bottle/drift-bottle.component_20241227185852.scss

@@ -0,0 +1,100 @@
+:host {
+    display: block;
+}
+
+/* 设置页面背景色 */
+ion-content {
+    --background: transparent; /* 确保内容背景透明 */
+    position: relative;
+    height: 100vh; /* 确保内容高度占满整个视口 */
+}
+
+.top-image {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 80%; /* 图片占据页面的70%高度 */
+    overflow: hidden;
+    z-index: 0; /* 确保图片在工具栏之下 */
+    
+}
+
+.top-image img {
+    width: 100%;
+    height: 100%;
+    object-fit: fill; /* 使图片填充整个容器并可能被拉伸 */
+    clip-path: ellipse(140% 130% at 50% -30%); /* 使用椭圆剪裁路径 */
+}
+
+.ripple {
+    position: absolute;
+    border-radius: 50%;
+    background-color: rgba(255, 255, 255, 0.6); /* 白色半透明背景 */
+    transform: scale(0);
+    animation: rippleEffect 0.6s ease-out;
+}
+
+@keyframes rippleEffect {
+    to {
+        transform: scale(3);
+        opacity: 0;
+    }
+}
+
+.button-container {
+    position: absolute;
+    bottom: 15%; /* 调整此值以改变按钮距离底部的距离 */
+    z-index: 2; /* 确保按钮在图片之上 */
+}
+
+.left-button {
+    left: 30px; /* 距离左边的距离 */
+}
+
+.right-button {
+    right: 30px; /* 距离右边的距离 */
+}
+
+.middle-button {
+    left: 50%;
+    transform: translateX(-50%) translateY(50%); /* 向下移动一点 */
+}
+
+.button-container img {
+    width: 60px; /* 按钮图片宽度 */
+    height: 60px; /* 按钮图片高度 */
+    display: block;
+    transition: transform 0.3s ease; /* 添加过渡效果 */
+}
+
+.circular-button {
+    width: 60px; /* 按钮图片宽度 */
+    height: 60px; /* 按钮图片高度 */
+    border-radius: 50%; /* 将图片剪裁为圆形 */
+    object-fit: cover; /* 保证图片填充圆形区域 */
+    transform: scale(1.5); /* 放大1.5倍 */
+    transform-origin: center; /* 放大的基点为中心 */
+    transition: transform 0.3s ease; /* 添加平滑过渡效果 */
+}
+
+.circular-button:hover {
+    transform: scale(1.6); /* 鼠标悬停时稍微再放大一点 */
+}
+
+.small-circular-button {
+    width: 50px; /* 更小圆形按钮的大小 */
+    height: 50px;
+    border-radius: 50%;
+}
+
+.custom-button {
+    font-size: 18px; /* 按钮字体大小 */
+    border-radius: 6px; /* 圆角按钮 */
+    color: rgb(69, 166, 180); /* 字体颜色 */
+    transition: opacity 0.3s, color 0.3s; /* 添加过渡效果 */
+}
+
+.custom-button:hover {
+    color: rgb(49, 126, 140); /* 悬停时字体颜色变深 */
+}

+ 76 - 0
.history/soul-app/src/app/drift-bottle/drift-bottle.component_20241227190150.scss

@@ -0,0 +1,76 @@
+:host {
+    display: block;
+}
+
+/* 设置页面背景色 */
+ion-content {
+    --background: transparent; /* 确保内容背景透明 */
+    position: relative;
+    height: 100vh; /* 确保内容高度占满整个视口 */
+}
+
+.top-image {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 80%; /* 图片占据页面的70%高度 */
+    overflow: hidden;
+    z-index: 0; /* 确保图片在工具栏之下 */
+    
+}
+
+.top-image img {
+    width: 100%;
+    height: 100%;
+    object-fit: fill; /* 使图片填充整个容器并可能被拉伸 */
+    clip-path: ellipse(140% 130% at 50% -30%); /* 使用椭圆剪裁路径 */
+}
+
+.ripple {
+    position: absolute;
+    border-radius: 50%;
+    background-color: rgba(255, 255, 255, 0.6); /* 白色半透明背景 */
+    transform: scale(0);
+    animation: rippleEffect 0.6s ease-out;
+}
+
+@keyframes rippleEffect {
+    to {
+        transform: scale(3);
+        opacity: 0;
+    }
+}
+
+.button-container {
+    position: absolute;
+    bottom: 15%; /* 调整此值以改变按钮距离底部的距离 */
+    z-index: 2; /* 确保按钮在图片之上 */
+}
+
+.left-button {
+    left: 30px; /* 距离左边的距离 */
+}
+
+.right-button {
+    right: 30px; /* 距离右边的距离 */
+}
+
+.middle-button {
+    left: 50%;
+    transform: translateX(-50%) translateY(50%); /* 向下移动一点 */
+}
+
+.circular-button {
+    width: 60px; /* 按钮图片宽度 */
+    height: 60px; /* 按钮图片高度 */
+    border-radius: 50%; /* 将图片剪裁为圆形 */
+    object-fit: cover; /* 保证图片填充圆形区域 */
+    transform: scale(1.5); /* 放大1.5倍 */
+    transform-origin: center; /* 放大的基点为中心 */
+    transition: transform 0.3s ease; /* 添加平滑过渡效果 */
+}
+
+.circular-button:hover {
+    transform: scale(1.6); /* 鼠标悬停时稍微再放大一点 */
+}

+ 114 - 0
.history/soul-app/src/app/drift-bottle/drift-bottle.component_20241227191022.ts

@@ -0,0 +1,114 @@
+import { Component, OnInit, OnDestroy, Renderer2, ElementRef, ViewChild } from '@angular/core';
+import { Router } from '@angular/router';
+import { IonicModule } from '@ionic/angular';
+import { openThrowDriftBottleModal } from '../throw-drift-bottle/throw-drift-bottle.component';
+import { ModalController } from '@ionic/angular/standalone';
+import { HttpClient } from '@angular/common/http';
+import { CloudObject, CloudQuery } from 'src/lib/ncloud';
+import { UserService } from 'src/app/user.service'; // 假设这是你的用户服务
+import { CommonModule } from '@angular/common'; // 导入 CommonModule
+
+@Component({
+  selector: 'app-drift-bottle',
+  templateUrl: './drift-bottle.component.html',
+  styleUrls: ['./drift-bottle.component.scss'],
+  standalone: true,
+  imports: [
+    IonicModule,
+    CommonModule, // 添加 CommonModule
+    // 其他导入项...
+  ]
+})
+export class DriftBottleComponent implements OnInit, OnDestroy {
+  alertHeader: string = '';
+  alertMessage: string = '';
+
+  @ViewChild('backgroundAudio', { static: false }) audioElement!: ElementRef<HTMLAudioElement>;
+
+  constructor(
+    private router: Router,
+    private modalCtrl: ModalController,
+    private http: HttpClient,
+    private renderer: Renderer2,
+    private userService: UserService // 注入用户服务
+  ) {}
+
+  ngOnInit() {
+    if (this.audioElement && this.audioElement.nativeElement) {
+      const audio = this.audioElement.nativeElement;
+      audio.loop = true;
+      audio.play().catch(error => {
+        console.error('Failed to play audio:', error);
+      });
+    } else {
+      console.warn('Audio element not found');
+    }
+  }
+
+  ngOnDestroy() {
+    if (this.audioElement && this.audioElement.nativeElement) {
+      const audio = this.audioElement.nativeElement;
+      audio.pause();
+      audio.currentTime = 0; // 重置音频时间
+      console.log('Audio element paused and reset');
+    } else {
+      console.warn('Audio element not found during destroy');
+    }
+    console.log('ngOnDestroy called');
+  }
+
+  throwDriftBottleModal() {
+    openThrowDriftBottleModal(this.modalCtrl);
+  }
+//点击捞一个时,随机打捞一个状态为漂流中的漂流瓶,将其状态(status)改为被打捞,打捞时间(catchtime)改为当前时间,打捞者(catcher)改为该用户的username
+//如果打捞成功,则在页面中间显示“打捞成功!快去看看吧!”,如果数据库中没有状态为drifting的漂流瓶,则打捞失败,在页面中间显示“没捞着哭哭~”
+  catchDriftBottle() {
+    const query = new CloudQuery("DriftBottle");
+    query.equalTo("status", "drifting");
+
+    query.find().then((driftingBottles: any[]) => {
+      if (driftingBottles.length === 0) {
+        this.alertHeader = '失败';
+        this.alertMessage = '没捞到…';
+        return;
+      }
+
+      const randomIndex = Math.floor(Math.random() * driftingBottles.length);
+      const bottleToCatch = driftingBottles[randomIndex];
+
+      const username = this.userService.getUsername(); // 获取当前用户的用户名
+      if (!username) {
+        console.error('用户未登录或未找到用户名');
+        this.alertHeader = '错误';
+        this.alertMessage = '用户未登录,请先登录。';
+        return;
+      }
+
+      bottleToCatch.set("status", "caught");
+      bottleToCatch.set("catcher", username); // 设置打捞者
+      bottleToCatch.set("catchTime", new Date()); // 设置打捞时间
+
+      bottleToCatch.save().then(() => {
+        this.alertHeader = '成功';
+        this.alertMessage = '捞到啦!快去看看吧!';
+      }).catch((err: any) => {
+        console.error('更新漂流瓶状态时出错:', err);
+        this.alertHeader = '错误';
+        this.alertMessage = '发生错误,请重试。';
+      });
+    }).catch((err) => {
+      console.error('获取漂流瓶时出错:', err);
+      this.alertHeader = '错误';
+      this.alertMessage = '发生错误,请重试。';
+    });
+  }
+
+  dismissAlert() {
+    this.alertHeader = '';
+    this.alertMessage = '';
+  }
+
+  goMydriftbottle() {
+    this.router.navigate(['tabs/my-drift-bottle']);
+  }
+}

+ 100 - 0
.history/soul-app/src/app/drift-bottle/drift-bottle.component_20241227191037.scss

@@ -0,0 +1,100 @@
+:host {
+    display: block;
+}
+
+/* 设置页面背景色 */
+ion-content {
+    --background: transparent; /* 确保内容背景透明 */
+    position: relative;
+    height: 100vh; /* 确保内容高度占满整个视口 */
+}
+
+.top-image {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 80%; /* 图片占据页面的70%高度 */
+    overflow: hidden;
+    z-index: 0; /* 确保图片在工具栏之下 */
+    
+}
+
+.top-image img {
+    width: 100%;
+    height: 100%;
+    object-fit: fill; /* 使图片填充整个容器并可能被拉伸 */
+    clip-path: ellipse(140% 130% at 50% -30%); /* 使用椭圆剪裁路径 */
+}
+
+.ripple {
+    position: absolute;
+    border-radius: 50%;
+    background-color: rgba(255, 255, 255, 0.6); /* 白色半透明背景 */
+    transform: scale(0);
+    animation: rippleEffect 0.6s ease-out;
+}
+
+@keyframes rippleEffect {
+    to {
+        transform: scale(3);
+        opacity: 0;
+    }
+}
+
+.button-container {
+    position: absolute;
+    bottom: 15%; /* 调整此值以改变按钮距离底部的距离 */
+    z-index: 2; /* 确保按钮在图片之上 */
+}
+
+.left-button {
+    left: 30px; /* 距离左边的距离 */
+}
+
+.right-button {
+    right: 30px; /* 距离右边的距离 */
+}
+
+.middle-button {
+    left: 50%;
+    transform: translateX(-50%) translateY(50%); /* 向下移动一点 */
+}
+
+.button-container img {
+    width: 60px; /* 按钮图片宽度 */
+    height: 60px; /* 按钮图片高度 */
+    display: block;
+    transition: transform 0.3s ease; /* 添加过渡效果 */
+}
+
+.circular-button {
+    width: 60px; /* 按钮图片宽度 */
+    height: 60px; /* 按钮图片高度 */
+    border-radius: 50%; /* 将图片剪裁为圆形 */
+    object-fit: cover; /* 保证图片填充圆形区域 */
+    transform: scale(1.5); /* 放大1.5倍 */
+    transform-origin: center; /* 放大的基点为中心 */
+    transition: transform 0.3s ease; /* 添加平滑过渡效果 */
+}
+
+.circular-button:hover {
+    transform: scale(1.6); /* 鼠标悬停时稍微再放大一点 */
+}
+
+.small-circular-button {
+    width: 50px; /* 更小圆形按钮的大小 */
+    height: 50px;
+    border-radius: 50%;
+}
+
+.custom-button {
+    font-size: 18px; /* 按钮字体大小 */
+    border-radius: 6px; /* 圆角按钮 */
+    color: rgb(69, 166, 180); /* 字体颜色 */
+    transition: opacity 0.3s, color 0.3s; /* 添加过渡效果 */
+}
+
+.custom-button:hover {
+    color: rgb(49, 126, 140); /* 悬停时字体颜色变深 */
+}

+ 14 - 15
soul-app/src/app/drift-bottle/drift-bottle.component.scss

@@ -1,4 +1,3 @@
-/* drift-bottle.component.scss */
 :host {
     display: block;
 }
@@ -21,13 +20,13 @@ ion-content {
     
 }
 
-
 .top-image img {
     width: 100%;
     height: 100%;
     object-fit: fill; /* 使图片填充整个容器并可能被拉伸 */
     clip-path: ellipse(140% 130% at 50% -30%); /* 使用椭圆剪裁路径 */
 }
+
 .ripple {
     position: absolute;
     border-radius: 50%;
@@ -66,7 +65,9 @@ ion-content {
     width: 60px; /* 按钮图片宽度 */
     height: 60px; /* 按钮图片高度 */
     display: block;
+    transition: transform 0.3s ease; /* 添加过渡效果 */
 }
+
 .circular-button {
     width: 60px; /* 按钮图片宽度 */
     height: 60px; /* 按钮图片高度 */
@@ -76,26 +77,24 @@ ion-content {
     transform-origin: center; /* 放大的基点为中心 */
     transition: transform 0.3s ease; /* 添加平滑过渡效果 */
 }
+
+.circular-button:hover {
+    transform: scale(1.6); /* 鼠标悬停时稍微再放大一点 */
+}
+
 .small-circular-button {
     width: 50px; /* 更小圆形按钮的大小 */
     height: 50px;
     border-radius: 50%;
-  }
-  .custom-button {
+}
+
+.custom-button {
     font-size: 18px; /* 按钮字体大小 */
     border-radius: 6px; /* 圆角按钮 */
     color: rgb(69, 166, 180); /* 字体颜色 */
     transition: opacity 0.3s, color 0.3s; /* 添加过渡效果 */
-    
-  }
-
-/* 如果需要,可以在悬停时添加一些效果 */
-.circular-button:hover {
-    transform: scale(1.6); /* 鼠标悬停时稍微再放大一点 */
 }
 
-
-  
-  
-  
-  
+.custom-button:hover {
+    color: rgb(49, 126, 140); /* 悬停时字体颜色变深 */
+}

+ 4 - 1
soul-app/src/app/drift-bottle/drift-bottle.component.ts

@@ -6,6 +6,7 @@ import { ModalController } from '@ionic/angular/standalone';
 import { HttpClient } from '@angular/common/http';
 import { CloudObject, CloudQuery } from 'src/lib/ncloud';
 import { UserService } from 'src/app/user.service'; // 假设这是你的用户服务
+import { CommonModule } from '@angular/common'; // 导入 CommonModule
 
 @Component({
   selector: 'app-drift-bottle',
@@ -14,6 +15,7 @@ import { UserService } from 'src/app/user.service'; // 假设这是你的用户
   standalone: true,
   imports: [
     IonicModule,
+    CommonModule, // 添加 CommonModule
     // 其他导入项...
   ]
 })
@@ -58,7 +60,8 @@ export class DriftBottleComponent implements OnInit, OnDestroy {
   throwDriftBottleModal() {
     openThrowDriftBottleModal(this.modalCtrl);
   }
-
+//点击捞一个时,随机打捞一个状态为漂流中的漂流瓶,将其状态(status)改为被打捞,打捞时间(catchtime)改为当前时间,打捞者(catcher)改为该用户的username
+//如果打捞成功,则在页面中间显示“打捞成功!快去看看吧!”,如果数据库中没有状态为drifting的漂流瓶,则打捞失败,在页面中间显示“没捞着哭哭~”
   catchDriftBottle() {
     const query = new CloudQuery("DriftBottle");
     query.equalTo("status", "drifting");