diff --git a/android/.kotlin/errors/errors-1763427903700.log b/android/.kotlin/errors/errors-1763427903700.log
new file mode 100644
index 0000000..5aeb2b9
--- /dev/null
+++ b/android/.kotlin/errors/errors-1763427903700.log
@@ -0,0 +1,198 @@
+kotlin version: 2.1.0
+error message: Daemon compilation failed: null
+java.lang.Exception
+ at org.jetbrains.kotlin.daemon.common.CompileService$CallResult$Error.get(CompileService.kt:69)
+ at org.jetbrains.kotlin.daemon.common.CompileService$CallResult$Error.get(CompileService.kt:65)
+ at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemon(GradleKotlinCompilerWork.kt:240)
+ at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemonOrFallbackImpl(GradleKotlinCompilerWork.kt:159)
+ at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:111)
+ at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:76)
+ at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:63)
+ at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:66)
+ at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:62)
+ at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:100)
+ at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:62)
+ at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
+ at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
+ at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
+ at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
+ at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
+ at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
+ at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
+ at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
+ at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
+ at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
+ at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:59)
+ at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:174)
+ at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
+ at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194)
+ at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127)
+ at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169)
+ at org.gradle.internal.Factories$1.create(Factories.java:31)
+ at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:263)
+ at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
+ at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132)
+ at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
+ at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133)
+ at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
+ at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
+ at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
+ at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:48)
+ at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
+ at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
+ at java.base/java.lang.Thread.run(Unknown Source)
+Caused by: java.lang.AssertionError: java.lang.Exception: Could not close incremental caches in D:\www\dating_touchme_app\build\shared_preferences_android\kotlin\compileDebugKotlin\cacheable\caches-jvm\jvm\kotlin: class-fq-name-to-source.tab, source-to-classes.tab, internal-name-to-source.tab
+ at org.jetbrains.kotlin.com.google.common.io.Closer.close(Closer.java:236)
+ at org.jetbrains.kotlin.incremental.IncrementalCachesManager.close(IncrementalCachesManager.kt:55)
+ at kotlin.io.CloseableKt.closeFinally(Closeable.kt:56)
+ at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compileNonIncrementally(IncrementalCompilerRunner.kt:293)
+ at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compile(IncrementalCompilerRunner.kt:129)
+ at org.jetbrains.kotlin.daemon.CompileServiceImplBase.execIncrementalCompiler(CompileServiceImpl.kt:674)
+ at org.jetbrains.kotlin.daemon.CompileServiceImplBase.access$execIncrementalCompiler(CompileServiceImpl.kt:91)
+ at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1659)
+ at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Unknown Source)
+ at java.base/java.lang.reflect.Method.invoke(Unknown Source)
+ at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
+ at java.rmi/sun.rmi.transport.Transport$1.run(Unknown Source)
+ at java.rmi/sun.rmi.transport.Transport$1.run(Unknown Source)
+ at java.base/java.security.AccessController.doPrivileged(Unknown Source)
+ at java.rmi/sun.rmi.transport.Transport.serviceCall(Unknown Source)
+ at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
+ at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
+ at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(Unknown Source)
+ at java.base/java.security.AccessController.doPrivileged(Unknown Source)
+ at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
+ ... 3 more
+Caused by: java.lang.Exception: Could not close incremental caches in D:\www\dating_touchme_app\build\shared_preferences_android\kotlin\compileDebugKotlin\cacheable\caches-jvm\jvm\kotlin: class-fq-name-to-source.tab, source-to-classes.tab, internal-name-to-source.tab
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.forEachMapSafe(BasicMapsOwner.kt:95)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.close(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.com.google.common.io.Closer.close(Closer.java:223)
+ ... 22 more
+ Suppressed: java.lang.IllegalArgumentException: this and base files have different roots: C:\Users\Administrator\AppData\Local\Pub\Cache\hosted\pub.flutter-io.cn\shared_preferences_android-2.4.16\android\src\main\kotlin\io\flutter\plugins\sharedpreferences\MessagesAsync.g.kt and D:\www\dating_touchme_app\android.
+ at kotlin.io.FilesKt__UtilsKt.toRelativeString(Utils.kt:117)
+ at kotlin.io.FilesKt__UtilsKt.relativeTo(Utils.kt:128)
+ at org.jetbrains.kotlin.incremental.storage.RelocatableFileToPathConverter.toPath(RelocatableFileToPathConverter.kt:24)
+ at org.jetbrains.kotlin.incremental.storage.FileDescriptor.save(FileToPathConverter.kt:33)
+ at org.jetbrains.kotlin.incremental.storage.FileDescriptor.save(FileToPathConverter.kt:30)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.doPut(PersistentMapImpl.java:443)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.put(PersistentMapImpl.java:422)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentHashMap.put(PersistentHashMap.java:105)
+ at org.jetbrains.kotlin.incremental.storage.LazyStorage.set(LazyStorage.kt:80)
+ at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.applyChanges(InMemoryStorage.kt:108)
+ at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.close(InMemoryStorage.kt:136)
+ at org.jetbrains.kotlin.incremental.storage.PersistentStorageWrapper.close(PersistentStorage.kt:124)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.forEachMapSafe(BasicMapsOwner.kt:87)
+ ... 24 more
+ Suppressed: java.lang.IllegalArgumentException: this and base files have different roots: C:\Users\Administrator\AppData\Local\Pub\Cache\hosted\pub.flutter-io.cn\shared_preferences_android-2.4.16\android\src\main\kotlin\io\flutter\plugins\sharedpreferences\MessagesAsync.g.kt and D:\www\dating_touchme_app\android.
+ at kotlin.io.FilesKt__UtilsKt.toRelativeString(Utils.kt:117)
+ at kotlin.io.FilesKt__UtilsKt.relativeTo(Utils.kt:128)
+ at org.jetbrains.kotlin.incremental.storage.RelocatableFileToPathConverter.toPath(RelocatableFileToPathConverter.kt:24)
+ at org.jetbrains.kotlin.incremental.storage.FileDescriptor.getHashCode(FileToPathConverter.kt:50)
+ at org.jetbrains.kotlin.incremental.storage.FileDescriptor.getHashCode(FileToPathConverter.kt:30)
+ at org.jetbrains.kotlin.com.intellij.util.containers.LinkedCustomHashMap.hashKey(LinkedCustomHashMap.java:109)
+ at org.jetbrains.kotlin.com.intellij.util.containers.LinkedCustomHashMap.remove(LinkedCustomHashMap.java:153)
+ at org.jetbrains.kotlin.com.intellij.util.containers.SLRUMap.remove(SLRUMap.java:89)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.flushAppendCache(PersistentMapImpl.java:999)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.doPut(PersistentMapImpl.java:451)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.put(PersistentMapImpl.java:422)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentHashMap.put(PersistentHashMap.java:105)
+ at org.jetbrains.kotlin.incremental.storage.LazyStorage.set(LazyStorage.kt:80)
+ at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.applyChanges(InMemoryStorage.kt:108)
+ at org.jetbrains.kotlin.incremental.storage.AppendableInMemoryStorage.applyChanges(InMemoryStorage.kt:179)
+ at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.close(InMemoryStorage.kt:136)
+ at org.jetbrains.kotlin.incremental.storage.AppendableSetBasicMap.close(BasicMap.kt:157)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.forEachMapSafe(BasicMapsOwner.kt:87)
+ ... 24 more
+ Suppressed: java.lang.IllegalArgumentException: this and base files have different roots: C:\Users\Administrator\AppData\Local\Pub\Cache\hosted\pub.flutter-io.cn\shared_preferences_android-2.4.16\android\src\main\kotlin\io\flutter\plugins\sharedpreferences\MessagesAsync.g.kt and D:\www\dating_touchme_app\android.
+ at kotlin.io.FilesKt__UtilsKt.toRelativeString(Utils.kt:117)
+ at kotlin.io.FilesKt__UtilsKt.relativeTo(Utils.kt:128)
+ at org.jetbrains.kotlin.incremental.storage.RelocatableFileToPathConverter.toPath(RelocatableFileToPathConverter.kt:24)
+ at org.jetbrains.kotlin.incremental.storage.FileDescriptor.save(FileToPathConverter.kt:33)
+ at org.jetbrains.kotlin.incremental.storage.FileDescriptor.save(FileToPathConverter.kt:30)
+ at org.jetbrains.kotlin.incremental.storage.AppendableCollectionExternalizer.save(LazyStorage.kt:151)
+ at org.jetbrains.kotlin.incremental.storage.AppendableCollectionExternalizer.save(LazyStorage.kt:142)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.doPut(PersistentMapImpl.java:443)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.put(PersistentMapImpl.java:422)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentHashMap.put(PersistentHashMap.java:105)
+ at org.jetbrains.kotlin.incremental.storage.LazyStorage.set(LazyStorage.kt:80)
+ at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.applyChanges(InMemoryStorage.kt:108)
+ at org.jetbrains.kotlin.incremental.storage.AppendableInMemoryStorage.applyChanges(InMemoryStorage.kt:179)
+ at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.close(InMemoryStorage.kt:136)
+ at org.jetbrains.kotlin.incremental.storage.PersistentStorageWrapper.close(PersistentStorage.kt:124)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.forEachMapSafe(BasicMapsOwner.kt:87)
+ ... 24 more
+ Suppressed: java.lang.Exception: Could not close incremental caches in D:\www\dating_touchme_app\build\shared_preferences_android\kotlin\compileDebugKotlin\cacheable\caches-jvm\lookups: id-to-file.tab, file-to-id.tab
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.forEachMapSafe(BasicMapsOwner.kt:95)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.close(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.incremental.LookupStorage.close(LookupStorage.kt:155)
+ ... 23 more
+ Suppressed: java.lang.IllegalArgumentException: this and base files have different roots: C:\Users\Administrator\AppData\Local\Pub\Cache\hosted\pub.flutter-io.cn\shared_preferences_android-2.4.16\android\src\main\kotlin\io\flutter\plugins\sharedpreferences\MessagesAsync.g.kt and D:\www\dating_touchme_app\android.
+ at kotlin.io.FilesKt__UtilsKt.toRelativeString(Utils.kt:117)
+ at kotlin.io.FilesKt__UtilsKt.relativeTo(Utils.kt:128)
+ at org.jetbrains.kotlin.incremental.storage.RelocatableFileToPathConverter.toPath(RelocatableFileToPathConverter.kt:24)
+ at org.jetbrains.kotlin.incremental.storage.LegacyFileExternalizer.save(IdToFileMap.kt:51)
+ at org.jetbrains.kotlin.incremental.storage.LegacyFileExternalizer.save(IdToFileMap.kt:48)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.doPut(PersistentMapImpl.java:443)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.put(PersistentMapImpl.java:422)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentHashMap.put(PersistentHashMap.java:105)
+ at org.jetbrains.kotlin.incremental.storage.LazyStorage.set(LazyStorage.kt:80)
+ at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.applyChanges(InMemoryStorage.kt:108)
+ at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.close(InMemoryStorage.kt:136)
+ at org.jetbrains.kotlin.incremental.storage.PersistentStorageWrapper.close(PersistentStorage.kt:124)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.forEachMapSafe(BasicMapsOwner.kt:87)
+ ... 25 more
+ Suppressed: java.lang.IllegalArgumentException: this and base files have different roots: C:\Users\Administrator\AppData\Local\Pub\Cache\hosted\pub.flutter-io.cn\shared_preferences_android-2.4.16\android\src\main\kotlin\io\flutter\plugins\sharedpreferences\MessagesAsync.g.kt and D:\www\dating_touchme_app\android.
+ at kotlin.io.FilesKt__UtilsKt.toRelativeString(Utils.kt:117)
+ at kotlin.io.FilesKt__UtilsKt.relativeTo(Utils.kt:128)
+ at org.jetbrains.kotlin.incremental.storage.RelocatableFileToPathConverter.toPath(RelocatableFileToPathConverter.kt:24)
+ at org.jetbrains.kotlin.incremental.storage.FileDescriptor.getHashCode(FileToPathConverter.kt:50)
+ at org.jetbrains.kotlin.incremental.storage.FileDescriptor.getHashCode(FileToPathConverter.kt:30)
+ at org.jetbrains.kotlin.com.intellij.util.containers.LinkedCustomHashMap.hashKey(LinkedCustomHashMap.java:109)
+ at org.jetbrains.kotlin.com.intellij.util.containers.LinkedCustomHashMap.remove(LinkedCustomHashMap.java:153)
+ at org.jetbrains.kotlin.com.intellij.util.containers.SLRUMap.remove(SLRUMap.java:89)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.flushAppendCache(PersistentMapImpl.java:999)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.doPut(PersistentMapImpl.java:451)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.put(PersistentMapImpl.java:422)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentHashMap.put(PersistentHashMap.java:105)
+ at org.jetbrains.kotlin.incremental.storage.LazyStorage.set(LazyStorage.kt:80)
+ at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.applyChanges(InMemoryStorage.kt:108)
+ at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.close(InMemoryStorage.kt:136)
+ at org.jetbrains.kotlin.incremental.storage.PersistentStorageWrapper.close(PersistentStorage.kt:124)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.forEachMapSafe(BasicMapsOwner.kt:87)
+ ... 25 more
+ Suppressed: java.lang.Exception: Could not close incremental caches in D:\www\dating_touchme_app\build\shared_preferences_android\kotlin\compileDebugKotlin\cacheable\caches-jvm\inputs: source-to-output.tab
+ ... 25 more
+ Suppressed: java.lang.IllegalArgumentException: this and base files have different roots: C:\Users\Administrator\AppData\Local\Pub\Cache\hosted\pub.flutter-io.cn\shared_preferences_android-2.4.16\android\src\main\kotlin\io\flutter\plugins\sharedpreferences\MessagesAsync.g.kt and D:\www\dating_touchme_app\android.
+ at kotlin.io.FilesKt__UtilsKt.toRelativeString(Utils.kt:117)
+ at kotlin.io.FilesKt__UtilsKt.relativeTo(Utils.kt:128)
+ at org.jetbrains.kotlin.incremental.storage.RelocatableFileToPathConverter.toPath(RelocatableFileToPathConverter.kt:24)
+ at org.jetbrains.kotlin.incremental.storage.FileDescriptor.getHashCode(FileToPathConverter.kt:50)
+ at org.jetbrains.kotlin.incremental.storage.FileDescriptor.getHashCode(FileToPathConverter.kt:30)
+ at org.jetbrains.kotlin.com.intellij.util.containers.LinkedCustomHashMap.hashKey(LinkedCustomHashMap.java:109)
+ at org.jetbrains.kotlin.com.intellij.util.containers.LinkedCustomHashMap.remove(LinkedCustomHashMap.java:153)
+ at org.jetbrains.kotlin.com.intellij.util.containers.SLRUMap.remove(SLRUMap.java:89)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.flushAppendCache(PersistentMapImpl.java:999)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.doPut(PersistentMapImpl.java:451)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.put(PersistentMapImpl.java:422)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentHashMap.put(PersistentHashMap.java:105)
+ at org.jetbrains.kotlin.incremental.storage.LazyStorage.set(LazyStorage.kt:80)
+ at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.applyChanges(InMemoryStorage.kt:108)
+ at org.jetbrains.kotlin.incremental.storage.AppendableInMemoryStorage.applyChanges(InMemoryStorage.kt:179)
+ at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.close(InMemoryStorage.kt:136)
+ at org.jetbrains.kotlin.incremental.storage.AppendableSetBasicMap.close(BasicMap.kt:157)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.forEachMapSafe(BasicMapsOwner.kt:87)
+ ... 24 more
+
+
diff --git a/android/.kotlin/errors/errors-1763427903713.log b/android/.kotlin/errors/errors-1763427903713.log
new file mode 100644
index 0000000..b4f85e9
--- /dev/null
+++ b/android/.kotlin/errors/errors-1763427903713.log
@@ -0,0 +1,198 @@
+kotlin version: 2.1.0
+error message: Daemon compilation failed: null
+java.lang.Exception
+ at org.jetbrains.kotlin.daemon.common.CompileService$CallResult$Error.get(CompileService.kt:69)
+ at org.jetbrains.kotlin.daemon.common.CompileService$CallResult$Error.get(CompileService.kt:65)
+ at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemon(GradleKotlinCompilerWork.kt:240)
+ at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemonOrFallbackImpl(GradleKotlinCompilerWork.kt:159)
+ at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:111)
+ at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:76)
+ at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:63)
+ at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:66)
+ at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:62)
+ at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:100)
+ at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:62)
+ at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
+ at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
+ at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
+ at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
+ at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
+ at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
+ at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
+ at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
+ at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
+ at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
+ at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:59)
+ at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:174)
+ at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
+ at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194)
+ at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127)
+ at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169)
+ at org.gradle.internal.Factories$1.create(Factories.java:31)
+ at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:263)
+ at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
+ at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132)
+ at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
+ at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133)
+ at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
+ at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
+ at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
+ at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:48)
+ at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
+ at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
+ at java.base/java.lang.Thread.run(Unknown Source)
+Caused by: java.lang.AssertionError: java.lang.Exception: Could not close incremental caches in D:\www\dating_touchme_app\build\video_player_android\kotlin\compileDebugKotlin\cacheable\caches-jvm\jvm\kotlin: class-fq-name-to-source.tab, source-to-classes.tab, internal-name-to-source.tab
+ at org.jetbrains.kotlin.com.google.common.io.Closer.close(Closer.java:236)
+ at org.jetbrains.kotlin.incremental.IncrementalCachesManager.close(IncrementalCachesManager.kt:55)
+ at kotlin.io.CloseableKt.closeFinally(Closeable.kt:56)
+ at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compileNonIncrementally(IncrementalCompilerRunner.kt:293)
+ at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compile(IncrementalCompilerRunner.kt:129)
+ at org.jetbrains.kotlin.daemon.CompileServiceImplBase.execIncrementalCompiler(CompileServiceImpl.kt:674)
+ at org.jetbrains.kotlin.daemon.CompileServiceImplBase.access$execIncrementalCompiler(CompileServiceImpl.kt:91)
+ at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1659)
+ at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Unknown Source)
+ at java.base/java.lang.reflect.Method.invoke(Unknown Source)
+ at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
+ at java.rmi/sun.rmi.transport.Transport$1.run(Unknown Source)
+ at java.rmi/sun.rmi.transport.Transport$1.run(Unknown Source)
+ at java.base/java.security.AccessController.doPrivileged(Unknown Source)
+ at java.rmi/sun.rmi.transport.Transport.serviceCall(Unknown Source)
+ at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
+ at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
+ at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(Unknown Source)
+ at java.base/java.security.AccessController.doPrivileged(Unknown Source)
+ at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
+ ... 3 more
+Caused by: java.lang.Exception: Could not close incremental caches in D:\www\dating_touchme_app\build\video_player_android\kotlin\compileDebugKotlin\cacheable\caches-jvm\jvm\kotlin: class-fq-name-to-source.tab, source-to-classes.tab, internal-name-to-source.tab
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.forEachMapSafe(BasicMapsOwner.kt:95)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.close(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.com.google.common.io.Closer.close(Closer.java:223)
+ ... 22 more
+ Suppressed: java.lang.IllegalArgumentException: this and base files have different roots: C:\Users\Administrator\AppData\Local\Pub\Cache\hosted\pub.flutter-io.cn\video_player_android-2.8.19\android\src\main\kotlin\io\flutter\plugins\videoplayer\Messages.kt and D:\www\dating_touchme_app\android.
+ at kotlin.io.FilesKt__UtilsKt.toRelativeString(Utils.kt:117)
+ at kotlin.io.FilesKt__UtilsKt.relativeTo(Utils.kt:128)
+ at org.jetbrains.kotlin.incremental.storage.RelocatableFileToPathConverter.toPath(RelocatableFileToPathConverter.kt:24)
+ at org.jetbrains.kotlin.incremental.storage.FileDescriptor.save(FileToPathConverter.kt:33)
+ at org.jetbrains.kotlin.incremental.storage.FileDescriptor.save(FileToPathConverter.kt:30)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.doPut(PersistentMapImpl.java:443)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.put(PersistentMapImpl.java:422)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentHashMap.put(PersistentHashMap.java:105)
+ at org.jetbrains.kotlin.incremental.storage.LazyStorage.set(LazyStorage.kt:80)
+ at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.applyChanges(InMemoryStorage.kt:108)
+ at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.close(InMemoryStorage.kt:136)
+ at org.jetbrains.kotlin.incremental.storage.PersistentStorageWrapper.close(PersistentStorage.kt:124)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.forEachMapSafe(BasicMapsOwner.kt:87)
+ ... 24 more
+ Suppressed: java.lang.IllegalArgumentException: this and base files have different roots: C:\Users\Administrator\AppData\Local\Pub\Cache\hosted\pub.flutter-io.cn\video_player_android-2.8.19\android\src\main\kotlin\io\flutter\plugins\videoplayer\Messages.kt and D:\www\dating_touchme_app\android.
+ at kotlin.io.FilesKt__UtilsKt.toRelativeString(Utils.kt:117)
+ at kotlin.io.FilesKt__UtilsKt.relativeTo(Utils.kt:128)
+ at org.jetbrains.kotlin.incremental.storage.RelocatableFileToPathConverter.toPath(RelocatableFileToPathConverter.kt:24)
+ at org.jetbrains.kotlin.incremental.storage.FileDescriptor.getHashCode(FileToPathConverter.kt:50)
+ at org.jetbrains.kotlin.incremental.storage.FileDescriptor.getHashCode(FileToPathConverter.kt:30)
+ at org.jetbrains.kotlin.com.intellij.util.containers.LinkedCustomHashMap.hashKey(LinkedCustomHashMap.java:109)
+ at org.jetbrains.kotlin.com.intellij.util.containers.LinkedCustomHashMap.remove(LinkedCustomHashMap.java:153)
+ at org.jetbrains.kotlin.com.intellij.util.containers.SLRUMap.remove(SLRUMap.java:89)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.flushAppendCache(PersistentMapImpl.java:999)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.doPut(PersistentMapImpl.java:451)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.put(PersistentMapImpl.java:422)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentHashMap.put(PersistentHashMap.java:105)
+ at org.jetbrains.kotlin.incremental.storage.LazyStorage.set(LazyStorage.kt:80)
+ at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.applyChanges(InMemoryStorage.kt:108)
+ at org.jetbrains.kotlin.incremental.storage.AppendableInMemoryStorage.applyChanges(InMemoryStorage.kt:179)
+ at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.close(InMemoryStorage.kt:136)
+ at org.jetbrains.kotlin.incremental.storage.AppendableSetBasicMap.close(BasicMap.kt:157)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.forEachMapSafe(BasicMapsOwner.kt:87)
+ ... 24 more
+ Suppressed: java.lang.IllegalArgumentException: this and base files have different roots: C:\Users\Administrator\AppData\Local\Pub\Cache\hosted\pub.flutter-io.cn\video_player_android-2.8.19\android\src\main\kotlin\io\flutter\plugins\videoplayer\Messages.kt and D:\www\dating_touchme_app\android.
+ at kotlin.io.FilesKt__UtilsKt.toRelativeString(Utils.kt:117)
+ at kotlin.io.FilesKt__UtilsKt.relativeTo(Utils.kt:128)
+ at org.jetbrains.kotlin.incremental.storage.RelocatableFileToPathConverter.toPath(RelocatableFileToPathConverter.kt:24)
+ at org.jetbrains.kotlin.incremental.storage.FileDescriptor.save(FileToPathConverter.kt:33)
+ at org.jetbrains.kotlin.incremental.storage.FileDescriptor.save(FileToPathConverter.kt:30)
+ at org.jetbrains.kotlin.incremental.storage.AppendableCollectionExternalizer.save(LazyStorage.kt:151)
+ at org.jetbrains.kotlin.incremental.storage.AppendableCollectionExternalizer.save(LazyStorage.kt:142)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.doPut(PersistentMapImpl.java:443)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.put(PersistentMapImpl.java:422)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentHashMap.put(PersistentHashMap.java:105)
+ at org.jetbrains.kotlin.incremental.storage.LazyStorage.set(LazyStorage.kt:80)
+ at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.applyChanges(InMemoryStorage.kt:108)
+ at org.jetbrains.kotlin.incremental.storage.AppendableInMemoryStorage.applyChanges(InMemoryStorage.kt:179)
+ at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.close(InMemoryStorage.kt:136)
+ at org.jetbrains.kotlin.incremental.storage.PersistentStorageWrapper.close(PersistentStorage.kt:124)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.forEachMapSafe(BasicMapsOwner.kt:87)
+ ... 24 more
+ Suppressed: java.lang.Exception: Could not close incremental caches in D:\www\dating_touchme_app\build\video_player_android\kotlin\compileDebugKotlin\cacheable\caches-jvm\lookups: id-to-file.tab, file-to-id.tab
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.forEachMapSafe(BasicMapsOwner.kt:95)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.close(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.incremental.LookupStorage.close(LookupStorage.kt:155)
+ ... 23 more
+ Suppressed: java.lang.IllegalArgumentException: this and base files have different roots: C:\Users\Administrator\AppData\Local\Pub\Cache\hosted\pub.flutter-io.cn\video_player_android-2.8.19\android\src\main\kotlin\io\flutter\plugins\videoplayer\Messages.kt and D:\www\dating_touchme_app\android.
+ at kotlin.io.FilesKt__UtilsKt.toRelativeString(Utils.kt:117)
+ at kotlin.io.FilesKt__UtilsKt.relativeTo(Utils.kt:128)
+ at org.jetbrains.kotlin.incremental.storage.RelocatableFileToPathConverter.toPath(RelocatableFileToPathConverter.kt:24)
+ at org.jetbrains.kotlin.incremental.storage.LegacyFileExternalizer.save(IdToFileMap.kt:51)
+ at org.jetbrains.kotlin.incremental.storage.LegacyFileExternalizer.save(IdToFileMap.kt:48)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.doPut(PersistentMapImpl.java:443)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.put(PersistentMapImpl.java:422)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentHashMap.put(PersistentHashMap.java:105)
+ at org.jetbrains.kotlin.incremental.storage.LazyStorage.set(LazyStorage.kt:80)
+ at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.applyChanges(InMemoryStorage.kt:108)
+ at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.close(InMemoryStorage.kt:136)
+ at org.jetbrains.kotlin.incremental.storage.PersistentStorageWrapper.close(PersistentStorage.kt:124)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.forEachMapSafe(BasicMapsOwner.kt:87)
+ ... 25 more
+ Suppressed: java.lang.IllegalArgumentException: this and base files have different roots: C:\Users\Administrator\AppData\Local\Pub\Cache\hosted\pub.flutter-io.cn\video_player_android-2.8.19\android\src\main\kotlin\io\flutter\plugins\videoplayer\Messages.kt and D:\www\dating_touchme_app\android.
+ at kotlin.io.FilesKt__UtilsKt.toRelativeString(Utils.kt:117)
+ at kotlin.io.FilesKt__UtilsKt.relativeTo(Utils.kt:128)
+ at org.jetbrains.kotlin.incremental.storage.RelocatableFileToPathConverter.toPath(RelocatableFileToPathConverter.kt:24)
+ at org.jetbrains.kotlin.incremental.storage.FileDescriptor.getHashCode(FileToPathConverter.kt:50)
+ at org.jetbrains.kotlin.incremental.storage.FileDescriptor.getHashCode(FileToPathConverter.kt:30)
+ at org.jetbrains.kotlin.com.intellij.util.containers.LinkedCustomHashMap.hashKey(LinkedCustomHashMap.java:109)
+ at org.jetbrains.kotlin.com.intellij.util.containers.LinkedCustomHashMap.remove(LinkedCustomHashMap.java:153)
+ at org.jetbrains.kotlin.com.intellij.util.containers.SLRUMap.remove(SLRUMap.java:89)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.flushAppendCache(PersistentMapImpl.java:999)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.doPut(PersistentMapImpl.java:451)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.put(PersistentMapImpl.java:422)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentHashMap.put(PersistentHashMap.java:105)
+ at org.jetbrains.kotlin.incremental.storage.LazyStorage.set(LazyStorage.kt:80)
+ at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.applyChanges(InMemoryStorage.kt:108)
+ at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.close(InMemoryStorage.kt:136)
+ at org.jetbrains.kotlin.incremental.storage.PersistentStorageWrapper.close(PersistentStorage.kt:124)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.forEachMapSafe(BasicMapsOwner.kt:87)
+ ... 25 more
+ Suppressed: java.lang.Exception: Could not close incremental caches in D:\www\dating_touchme_app\build\video_player_android\kotlin\compileDebugKotlin\cacheable\caches-jvm\inputs: source-to-output.tab
+ ... 25 more
+ Suppressed: java.lang.IllegalArgumentException: this and base files have different roots: C:\Users\Administrator\AppData\Local\Pub\Cache\hosted\pub.flutter-io.cn\video_player_android-2.8.19\android\src\main\kotlin\io\flutter\plugins\videoplayer\Messages.kt and D:\www\dating_touchme_app\android.
+ at kotlin.io.FilesKt__UtilsKt.toRelativeString(Utils.kt:117)
+ at kotlin.io.FilesKt__UtilsKt.relativeTo(Utils.kt:128)
+ at org.jetbrains.kotlin.incremental.storage.RelocatableFileToPathConverter.toPath(RelocatableFileToPathConverter.kt:24)
+ at org.jetbrains.kotlin.incremental.storage.FileDescriptor.getHashCode(FileToPathConverter.kt:50)
+ at org.jetbrains.kotlin.incremental.storage.FileDescriptor.getHashCode(FileToPathConverter.kt:30)
+ at org.jetbrains.kotlin.com.intellij.util.containers.LinkedCustomHashMap.hashKey(LinkedCustomHashMap.java:109)
+ at org.jetbrains.kotlin.com.intellij.util.containers.LinkedCustomHashMap.remove(LinkedCustomHashMap.java:153)
+ at org.jetbrains.kotlin.com.intellij.util.containers.SLRUMap.remove(SLRUMap.java:89)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.flushAppendCache(PersistentMapImpl.java:999)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.doPut(PersistentMapImpl.java:451)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentMapImpl.put(PersistentMapImpl.java:422)
+ at org.jetbrains.kotlin.com.intellij.util.io.PersistentHashMap.put(PersistentHashMap.java:105)
+ at org.jetbrains.kotlin.incremental.storage.LazyStorage.set(LazyStorage.kt:80)
+ at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.applyChanges(InMemoryStorage.kt:108)
+ at org.jetbrains.kotlin.incremental.storage.AppendableInMemoryStorage.applyChanges(InMemoryStorage.kt:179)
+ at org.jetbrains.kotlin.incremental.storage.InMemoryStorage.close(InMemoryStorage.kt:136)
+ at org.jetbrains.kotlin.incremental.storage.AppendableSetBasicMap.close(BasicMap.kt:157)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner$close$1.invoke(BasicMapsOwner.kt:53)
+ at org.jetbrains.kotlin.incremental.storage.BasicMapsOwner.forEachMapSafe(BasicMapsOwner.kt:87)
+ ... 24 more
+
+
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index a2ad459..4a34cf8 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -4,6 +4,7 @@
+
_joinRtcChannel(RtcChannelData data) async {
+ Future _joinRtcChannel(String token, String channelName, int uid) async {
try {
await RTCManager.instance.joinChannel(
- token: data.token,
- channelId: data.channelId,
+ token: token,
+ channelId: channelName,
+ uid: uid
);
- Get.to(() => const LiveRoomPage(id: 0));
} catch (e) {
SmartDialog.showToast('加入频道失败:$e');
}
diff --git a/lib/controller/mine/edit_info_controller.dart b/lib/controller/mine/edit_info_controller.dart
index 4ea82a1..c468f53 100644
--- a/lib/controller/mine/edit_info_controller.dart
+++ b/lib/controller/mine/edit_info_controller.dart
@@ -1,3 +1,5 @@
+import 'dart:io';
+
import 'package:dating_touchme_app/controller/global.dart';
import 'package:dating_touchme_app/generated/assets.dart';
import 'package:dating_touchme_app/model/mine/address_data.dart';
@@ -5,13 +7,17 @@ import 'package:dating_touchme_app/model/mine/education_data.dart';
import 'package:dating_touchme_app/model/mine/occupation_data.dart';
import 'package:dating_touchme_app/model/mine/user_data.dart';
import 'package:dating_touchme_app/network/user_api.dart';
+import 'package:dating_touchme_app/oss/oss_manager.dart';
import 'package:dating_touchme_app/pages/mine/auth_center_page.dart';
import 'package:dating_touchme_app/pages/mine/my_wallet_page.dart';
import 'package:dating_touchme_app/pages/mine/rose_page.dart';
+import 'package:flustars/flustars.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get_storage/get_storage.dart';
+import 'package:image_picker/image_picker.dart';
+import 'package:permission_handler/permission_handler.dart';
class EditInfoController extends GetxController {
@@ -20,11 +26,7 @@ class EditInfoController extends GetxController {
final menuActive = 1.obs;
- List imgList = [
- "https://fastly.picsum.photos/id/64/800/800.jpg?hmac=NBZ4_-vqzD6p25oCeaW0H5vH-ql9zzei-SqJNeUo1QU",
- "https://fastly.picsum.photos/id/985/800/800.jpg?hmac=DfRt99HFbMJ96DlN-poOhruWYRsexESE94ilLC3g1rU",
- "https://fastly.picsum.photos/id/703/800/800.jpg?hmac=-bRTkPxnsiQ5kCo2tfXj6tFrXMD7YnVx7bQ0STno3Tg"
- ];
+
final nowSelect = 0.obs;
@@ -52,6 +54,31 @@ class EditInfoController extends GetxController {
final areaShowData = {}.obs;
+ final avatarUrl = ''.obs;
+ // 本地选择的头像文件路径(提交时先上传)
+ final avatarLocalPath = ''.obs;
+
+ final imgList = [].obs;
+
+ final location = "".obs;
+
+ final locationValue = [].obs;
+
+ final homeLocation = "".obs;
+
+ final homeLocationValue = [].obs;
+
+ final educationSelect = (-1).obs;
+
+ final occupation = "".obs;
+
+ final occupationValue = [].obs;
+
+ final incomeSelect = (-1).obs;
+
+ final maritalSelect = (-1).obs;
+
+ final propertySelect = (-1).obs;
@override
void onInit() {
@@ -175,4 +202,263 @@ class EditInfoController extends GetxController {
print(areaShowData);
}
+
+
+ // 选择头像 - 业务逻辑处理
+ Future handleCameraCapture(int type) async {
+ try {
+ // 请求相机权限
+ final ok = await _ensurePermission(
+ Permission.camera,
+ denyToast: '相机权限被拒绝,请在设置中允许访问相机',
+ );
+ if (!ok) return;
+
+ // 请求麦克风权限(部分设备拍照/录像会一并请求建议预授权)
+ await _ensurePermission(Permission.microphone, denyToast: '麦克风权限被拒绝');
+
+ // 权限通过后拍照
+ final ImagePicker picker = ImagePicker();
+ final XFile? photo = await picker.pickImage(source: ImageSource.camera);
+
+ if (photo != null) {
+ if(type == 1){
+ avatarLocalPath.value = photo.path;
+ }
+ await processSelectedImage(File(photo.path), type);
+ }
+ } catch (e) {
+ print('拍照失败: $e');
+ // 更友好的错误提示
+ if (e.toString().contains('permission') || e.toString().contains('权限')) {
+ SmartDialog.showToast('相机权限被拒绝,请在设置中允许访问相机');
+ } else if (e.toString().contains('camera') ||
+ e.toString().contains('相机')) {
+ SmartDialog.showToast('设备没有可用的相机');
+ } else {
+ SmartDialog.showToast('拍照失败,请重试');
+ }
+ }
+ }
+
+ Future handleGallerySelection(int type) async {
+ try {
+ // 请求相册/照片权限
+ // final ok = await _ensurePermission(
+ // Permission.photos,
+ // // Android 上 photos 等价于 storage/mediaLibrary,permission_handler 会映射
+ // denyToast: '相册权限被拒绝,请在设置中允许访问相册',
+
+ // );
+ // if (!ok) return;
+
+ // 从相册选择图片
+ final ImagePicker picker = ImagePicker();
+ final XFile? image = await picker.pickImage(source: ImageSource.gallery);
+
+ if (image != null) {
+ if(type == 1){
+ avatarLocalPath.value = image.path;
+ }
+ await processSelectedImage(File(image.path), type);
+ }
+ } catch (e) {
+ print('选择图片失败: $e');
+ // 更友好的错误提示
+ if (e.toString().contains('permission') || e.toString().contains('权限')) {
+ SmartDialog.showToast('相册权限被拒绝,请在设置中允许访问相册');
+ } else {
+ SmartDialog.showToast('选择图片失败,请重试');
+ }
+ }
+ }
+
+ // 通用权限申请
+ Future _ensurePermission(Permission permission, {String? denyToast}) async {
+ var status = await permission.status;
+ if (status.isGranted) return true;
+
+ if (status.isDenied || status.isRestricted || status.isLimited) {
+ status = await permission.request();
+ if (status.isGranted) return true;
+ if (denyToast != null) SmartDialog.showToast(denyToast);
+ return false;
+ }
+
+ if (status.isPermanentlyDenied) {
+ if (denyToast != null) SmartDialog.showToast('$denyToast,前往系统设置开启');
+ // 延迟弹设置,避免与弹窗冲突
+ Future.delayed(const Duration(milliseconds: 300), openAppSettings);
+ return false;
+ }
+ return false;
+ }
+
+
+ // 处理选中的图片
+ Future processSelectedImage(File imageFile, int type) async {
+ if(type == 1){
+ try {
+ // 显示加载提示
+ SmartDialog.showLoading(msg: '上传头像中...');
+ String objectName = '${DateUtil.getNowDateMs()}.${imageFile.path.split('.').last}';
+ String imageUrl = await OSSManager.instance.uploadFile(imageFile.readAsBytesSync(), objectName);
+ print('上传成功,图片URL: $imageUrl');
+ avatarUrl.value = imageUrl;
+ SmartDialog.dismiss();
+ SmartDialog.showToast('头像上传成功');
+ } catch (e) {
+ SmartDialog.dismiss();
+ print('处理图片失败: $e');
+ SmartDialog.showToast('上传头像失败,请重试');
+ }
+ } else {
+ try {
+ // 显示加载提示
+ SmartDialog.showLoading(msg: '上传相册中...');
+ String objectName = '${DateUtil.getNowDateMs()}.${imageFile.path.split('.').last}';
+ String imageUrl = await OSSManager.instance.uploadFile(imageFile.readAsBytesSync(), objectName);
+ print('上传成功,图片URL: $imageUrl');
+ imgList.add(imageUrl);
+ SmartDialog.dismiss();
+ SmartDialog.showToast('上传设置成功');
+ } catch (e) {
+ SmartDialog.dismiss();
+ print('处理图片失败: $e');
+ SmartDialog.showToast('上传相册失败,请重试');
+ }
+ }
+ }
+
+ saveData() async {
+ if(avatarUrl.value == ""){
+ SmartDialog.showToast('请上传头像');
+ return;
+ }
+ if(imgList.isEmpty){
+ SmartDialog.showToast('请上传相册');
+ return;
+ }
+ if(locationValue.isEmpty){
+ SmartDialog.showToast('请选择所在地');
+ return;
+ }
+ if(homeLocationValue.isEmpty){
+ SmartDialog.showToast('请选择家乡');
+ return;
+ }
+ if(educationSelect.value == -1){
+ SmartDialog.showToast('请选择学历');
+ return;
+ }
+ if(incomeSelect.value == -1){
+ SmartDialog.showToast('请选择收入');
+ return;
+ }
+ if(maritalSelect.value == -1){
+ SmartDialog.showToast('请选择婚姻状况');
+ return;
+ }
+ if(occupationValue.isEmpty){
+ SmartDialog.showToast('请选择职业');
+ return;
+ }
+ if(propertySelect.value == -1){
+ SmartDialog.showToast('请选择房产状况');
+ return;
+ }
+ try {
+ final avatarPayload = {
+ 'miId': userData.value?.id ?? 0,
+ 'authenticationCode': '8',
+ 'value': '0',
+ 'imgUrl': avatarUrl.value.isNotEmpty ? [avatarUrl.value] : ['0'],
+ };
+ final avatarAuditResp = await _userApi.saveCertificationAudit(avatarPayload);
+ if (avatarAuditResp.data.isSuccess) {
+
+ } else{
+
+ SmartDialog.showToast(avatarAuditResp.data.message);
+
+ return;
+ }
+ } catch(e){
+ print('头像提交审核失败: $e');
+ SmartDialog.showToast('头像提交审核失败,请重试');
+ return;
+ }
+
+
+
+ try{
+ final imgPayload = {
+ 'miId': userData.value?.id ?? 0,
+ 'authenticationCode': '6',
+ 'value': '0',
+ 'imgUrl': imgList.isNotEmpty ? imgList : ['0'],
+ };
+
+ final imgAuditResp = await _userApi.saveCertificationAudit(imgPayload);
+ if (imgAuditResp.data.isSuccess) {
+
+ } else{
+
+ SmartDialog.showToast(imgAuditResp.data.message);
+
+ return;
+ }
+ } catch(e){
+ print('相册提交审核失败: $e');
+ SmartDialog.showToast('相册提交审核失败,请重试');
+ return;
+
+ }
+
+
+ try {
+ final payload = {
+ 'birthDate': userData.value?.birthDate ?? "",
+ 'birthYear': userData.value?.birthYear ?? "",
+ 'provinceCode': locationValue[0],
+ 'provinceName': location.value.split("-")[0],
+ 'cityCode': locationValue[1],
+ 'cityName': location.value.split("-")[1],
+ 'districtCode': locationValue[2],
+ 'districtName': location.value.split("-")[2],
+ "educationCode": educationList[educationSelect.value].value,
+ "height": height,
+ 'hometownProvinceCode': homeLocationValue[0],
+ 'hometownProvinceName': homeLocation.value.split("-")[0],
+ 'hometownCityCode': homeLocationValue[1],
+ 'hometownCityName': homeLocation.value.split("-")[1],
+ "incomeCode": incomeList[incomeSelect.value].value,
+ "maritalStatusCode": maritalList[maritalSelect.value].value,
+ "nickName": userData.value?.nickName ?? "",
+ 'occupation': occupation.value.split("-")[1],
+ 'occupationCode': occupationValue[1],
+ "propertyPermitsCode": propertyList[propertySelect.value].value,
+
+ };
+
+ final response = await _userApi.editOwnMarriageInformation(payload);
+ if (response.data.isSuccess) {
+
+ SmartDialog.showToast('保存成功');
+ Get.back();
+ }
+ else{
+
+ SmartDialog.showToast(response.data.message);
+
+ return;
+ }
+ } catch (e) {
+ print('资料提交审核失败: $e');
+ SmartDialog.showToast('资料提交审核失败,请重试');
+ return;
+ }
+
+ }
+
}
\ No newline at end of file
diff --git a/lib/controller/mine/login_controller.dart b/lib/controller/mine/login_controller.dart
index d2c0f0e..e502737 100644
--- a/lib/controller/mine/login_controller.dart
+++ b/lib/controller/mine/login_controller.dart
@@ -1,4 +1,5 @@
import 'dart:async';
+import 'package:dating_touchme_app/controller/global.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
@@ -110,14 +111,14 @@ class LoginController extends GetxController {
if (response.data.isSuccess) {
// 保存token和用户信息
if (response.data.data != null) {
- final loginData = response.data.data!;
- await storage.write('token', loginData.token);
- await storage.write('userId', loginData.userId);
- // 保存用户信息
- await storage.write('userInfo', loginData.toJson());
+ final result = response.data.data!;
+ GlobalData().userId = result.userId;
+ GlobalData().qnToken = result.token;
+ await storage.write('token', result.token);
+ // await storage.write('userId', result.userId);
// 登录成功后获取用户信息
- await _handleUserInfoRetrieval(loginData.userId);
+ await _handleUserInfoRetrieval(result.userId);
}
} else {
SmartDialog.showToast(response.data.message);
diff --git a/lib/controller/mine/mine_controller.dart b/lib/controller/mine/mine_controller.dart
index eeee6c0..4188ac1 100644
--- a/lib/controller/mine/mine_controller.dart
+++ b/lib/controller/mine/mine_controller.dart
@@ -1,13 +1,12 @@
import 'package:dating_touchme_app/controller/global.dart';
import 'package:dating_touchme_app/generated/assets.dart';
-import 'package:dating_touchme_app/model/mine/user_data.dart';
import 'package:dating_touchme_app/pages/mine/auth_center_page.dart';
import 'package:dating_touchme_app/pages/mine/my_wallet_page.dart';
import 'package:dating_touchme_app/pages/mine/rose_page.dart';
-import 'package:dating_touchme_app/pages/mine/setting_page.dart';
import 'package:dating_touchme_app/pages/mine/user_help_center_page.dart';
import 'package:get/get.dart';
-import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
+
+import '../../pages/setting/setting_page.dart';
class MineController extends GetxController {
diff --git a/lib/controller/mine/user_controller.dart b/lib/controller/mine/user_controller.dart
index efa1462..31fc56e 100644
--- a/lib/controller/mine/user_controller.dart
+++ b/lib/controller/mine/user_controller.dart
@@ -85,8 +85,8 @@ class UserController extends GetxController {
if (response.data.isSuccess && response.data.data != null) {
// 成功获取基础信息后,调用获取婚姻信息详情接口
final baseInfo = response.data.data!;
-
final result = await _userApi.getMarriageInformationDetail();
+ // print(result.data);
if (result.data.isSuccess) {
if(result.data.data == null){
if(isMain){
diff --git a/lib/controller/mine/user_info_controller.dart b/lib/controller/mine/user_info_controller.dart
index 358398b..e5a6458 100644
--- a/lib/controller/mine/user_info_controller.dart
+++ b/lib/controller/mine/user_info_controller.dart
@@ -1,4 +1,5 @@
import 'dart:io';
+import 'package:dating_touchme_app/controller/global.dart';
import 'package:dating_touchme_app/oss/oss_manager.dart';
import 'package:flustars/flustars.dart';
import 'package:get/get.dart';
@@ -6,6 +7,7 @@ import 'package:permission_handler/permission_handler.dart';
import 'package:get_storage/get_storage.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:image_picker/image_picker.dart';
+import '../../model/mine/user_data.dart';
import '../../network/user_api.dart';
import '../../pages/main/main_page.dart';
@@ -25,7 +27,12 @@ class UserInfoController extends GetxController {
// GetStorage实例,用于存储用户信息
final storage = GetStorage();
-
+ Map educationCodeMap = {
+ '大专以下': '0',
+ '大专': '1',
+ '本科': '2',
+ '硕士及以上': '3',
+ };
// UserApi实例
late UserApi _userApi;
@@ -221,12 +228,7 @@ class UserInfoController extends GetxController {
}
// 学历代码映射
- Map educationCodeMap = {
- '大专以下': '0',
- '大专': '1',
- '本科': '2',
- '硕士及以上': '3',
- };
+
return {
'birthYear': birthYear,
@@ -243,18 +245,13 @@ class UserInfoController extends GetxController {
if (!_validateForm()) {
return;
}
-
isSubmitting.value = true;
-
try {
-
-
// 构建请求参数
final params = _buildSubmitParams();
if (avatarUrl.value.isNotEmpty) {
params['avatarUrl'] = avatarUrl.value;
}
-
// 打印提交的信息
print('提交用户信息参数: $params');
@@ -264,40 +261,17 @@ class UserInfoController extends GetxController {
// 处理响应
if (response.data.isSuccess) {
// 获取 miId(资料id)
- String miId = '';
- final regData = response.data.data;
- if (regData != null) {
- miId = regData;
- await storage.write('miId', miId);
- } else {
- // 尝试从本地存储获取
- final stored = storage.read('miId');
- if (stored is String && stored.isNotEmpty) {
- miId = stored;
- } else {
- SmartDialog.showToast('获取资料ID失败,请重试');
- return;
- }
- }
-
+ String miId = response.data.data;
// 先调用认证审核保存接口(保存头像,authenticationCode=8)
try {
- final payload = {
- 'miId': miId,
- 'authenticationCode': '8',
- 'value': '0',
- 'imgUrl': avatarUrl.value.isNotEmpty ? [avatarUrl.value] : ['0'],
- };
-
- final auditResp = await _userApi.saveCertificationAudit(payload);
- if (auditResp.data.isSuccess) {
-
- }
- else{
-
- SmartDialog.showToast(auditResp.data.message);
-
- return;
+ if(avatarUrl.value.isNotEmpty){
+ final payload = {
+ 'miId': miId,
+ 'authenticationCode': '8',
+ 'value': '0',
+ 'imgUrl': avatarUrl.value.isNotEmpty ? [avatarUrl.value] : ['0'],
+ };
+ await _userApi.saveCertificationAudit(payload);
}
} catch (e) {
print('保存认证审核失败: $e');
@@ -306,23 +280,21 @@ class UserInfoController extends GetxController {
}
// 更新本地存储的用户信息
- final currentUserInfo = storage.read('userInfo') ?? {};
- if (currentUserInfo is Map) {
- currentUserInfo.addAll({
- 'gender': gender.value,
- 'nickname': nickname.value,
- 'birthday': birthday.value,
- 'education': education.value,
- 'avatarUrl': avatarUrl.value,
- });
- await storage.write('userInfo', currentUserInfo);
- }
-
+ GlobalData().userData!.id = miId;
+
+ final genderCode = gender.value == 'male' ? 0 : 1;// 1:男, 2:女
+ GlobalData().userData!.genderCode = genderCode;
+ GlobalData().userData!.nickName = nickname.value;
+ GlobalData().userData!.profilePhoto = avatarUrl.value;
+ GlobalData().userData!.education = education.value;
+ final code = educationCodeMap[education.value] ?? '0';
+ GlobalData().userData!.educationCode = int.parse(code);
// 显示成功提示
- SmartDialog.showToast('信息提交成功!');
-
+ SmartDialog.showToast('信息提交成功');
// 延迟后跳转
- Future.delayed(const Duration(milliseconds: 1500), () {
+ // await storage.write('token', GlobalData().qnToken);
+ await storage.write('userId', GlobalData().userId);
+ Future.delayed(const Duration(milliseconds: 100), () {
// 跳转到主页面(根据登录流程,应该跳转到MainPage)
Get.offAll(() => MainPage());
});
diff --git a/lib/controller/setting/notification_controller.dart b/lib/controller/setting/notification_controller.dart
new file mode 100644
index 0000000..057111c
--- /dev/null
+++ b/lib/controller/setting/notification_controller.dart
@@ -0,0 +1,103 @@
+// controllers/notification_controller.dart
+import 'package:get/get.dart';
+import 'package:permission_handler/permission_handler.dart';
+import 'package:app_settings/app_settings.dart';
+
+class NotificationController extends GetxController {
+ // 权限状态
+ final Rx notificationStatus = PermissionStatus.denied.obs;
+ final RxBool checking = false.obs;
+
+ // 初始化时检查权限
+ @override
+ void onInit() {
+ super.onInit();
+ // 延迟检查,确保服务已初始化
+ checkPermission();
+ }
+
+ // 检查通知权限状态
+ Future checkPermission() async {
+ checking.value = true;
+ try {
+ // 检查通知权限
+ final status = await Permission.notification.status;
+ notificationStatus.value = status;
+
+ print('通知权限状态: $status');
+ return status;
+ } catch (e) {
+ print('检查通知权限失败: $e');
+ return PermissionStatus.denied;
+ } finally {
+ checking.value = false;
+ }
+ }
+
+ // 请求通知权限
+ Future requestNotificationPermission() async {
+ try {
+ final status = await Permission.notification.request();
+ notificationStatus.value = status;
+
+ print('请求通知权限结果: $status');
+ return status;
+ } catch (e) {
+ print('请求通知权限失败: $e');
+ return PermissionStatus.denied;
+ }
+ }
+
+ // 打开应用设置页面(让用户手动开启权限)
+ Future openSettings() async {
+ try {
+ AppSettings.openAppSettings(
+ type: AppSettingsType.notification,
+ );
+ } catch (e) {
+ print('打开设置页面失败: $e');
+ }
+ }
+
+ // 检查是否有通知权限的便捷方法
+ // Future hasNotificationPermission() async {
+ // final status = await checkNotificationPermission();
+ // return status.isGranted || status.isLimited;
+ // }
+
+ // 获取权限状态描述
+ String getPermissionStatusText() {
+ switch (notificationStatus.value) {
+ case PermissionStatus.granted:
+ return '已开启';
+ case PermissionStatus.denied:
+ return '已拒绝';
+ case PermissionStatus.restricted:
+ return '受限制';
+ case PermissionStatus.limited:
+ return '部分授权';
+ case PermissionStatus.permanentlyDenied:
+ return '永久拒绝';
+ case PermissionStatus.provisional:
+ return '临时授权';
+ }
+ }
+
+ // 获取权限状态颜色
+ String getPermissionStatusColor() {
+ switch (notificationStatus.value) {
+ case PermissionStatus.granted:
+ return '绿色';
+ case PermissionStatus.denied:
+ return '橙色';
+ case PermissionStatus.restricted:
+ return '红色';
+ case PermissionStatus.limited:
+ return '蓝色';
+ case PermissionStatus.permanentlyDenied:
+ return '红色';
+ case PermissionStatus.provisional:
+ return '黄色';
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/controller/setting/setting_controller.dart b/lib/controller/setting/setting_controller.dart
new file mode 100644
index 0000000..6e2dd9b
--- /dev/null
+++ b/lib/controller/setting/setting_controller.dart
@@ -0,0 +1,230 @@
+import 'dart:async';
+import 'package:dating_touchme_app/controller/global.dart';
+import 'package:dating_touchme_app/extension/ex_widget.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:get/get.dart';
+import 'package:get_storage/get_storage.dart';
+import 'package:tdesign_flutter/tdesign_flutter.dart';
+import '../../generated/assets.dart';
+import 'package:package_info_plus/package_info_plus.dart';
+
+class SettingController extends GetxController {
+
+ final storage = GetStorage();
+ final appName = ''.obs;
+ final packageName = ''.obs;
+ final version = ''.obs;
+ final buildNumber = ''.obs;
+
+ @override
+ Future onInit() async {
+ super.onInit();
+ // 从全局依赖中获取UserApi
+ await getAppInfo();
+ }
+ // 获取验证码
+ Future getAppInfo() async {
+ try {
+ PackageInfo packageInfo = await PackageInfo.fromPlatform();
+ appName.value = packageInfo.appName;
+ packageName.value = packageInfo.packageName;
+ version.value = packageInfo.version;
+ buildNumber.value = packageInfo.buildNumber;
+ } catch (e) {
+ print('获取应用信息失败: $e');
+ }
+ }
+
+ Future checkVersion() async {
+ try {
+ _showUpdateDialog();
+ } catch (e) {
+ print('检测版本跟新失败: $e');
+ }
+ }
+
+ void logout(){
+ storage.erase();
+ GlobalData().logout();
+ }
+
+ // 弹出版本升级的dialog
+ void _showUpdateDialog(){
+ Navigator.of(Get.context!).push(TDSlidePopupRoute(
+ modalBarrierColor: TDTheme.of(Get.context!).fontGyColor2,
+ slideTransitionFrom: SlideTransitionFrom.center,
+ builder: (context) {
+ return Material(
+ color: Colors.transparent,
+ child: Container(
+ color: Colors.transparent,
+ width: 299.w,
+ padding: EdgeInsets.only(top: 56.w),
+ child: Stack(
+ clipBehavior: Clip.none,
+ children: [
+ Container(
+ width: 299.w,
+ padding: EdgeInsets.only(
+ top: 147.w,
+ left: 30.w,
+ right: 30.w,
+ bottom: 25.w
+ ),
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.all(Radius.circular(18.w)),
+ color: Colors.white
+ ),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Text(
+ "体验全新升级v1.2.0",
+ style: TextStyle(
+ fontSize: 16.w,
+ fontWeight: FontWeight.w500
+ ),
+ ),
+ SizedBox(height: 14.w,),
+ Row(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Container(
+ width: 2.w,
+ height: 5.w,
+ margin: EdgeInsets.only(
+ right: 10.w,
+ top: 6.w
+ ),
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.all(Radius.circular(2.w)),
+ color: const Color.fromRGBO(51, 51, 51, 1)
+ ),
+ ),
+ SizedBox(
+ width: 204.w,
+ child: Text(
+ "首页风格改版,更全面的内容,恍然一新的视觉用户体验。",
+ style: TextStyle(
+ fontSize: 12.w,
+ ),
+ ),
+ )
+ ],
+ ),
+ SizedBox(height: 8.w,),
+ Row(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Container(
+ width: 2.w,
+ height: 5.w,
+ margin: EdgeInsets.only(
+ right: 10.w,
+ top: 6.w
+ ),
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.all(Radius.circular(2.w)),
+ color: const Color.fromRGBO(51, 51, 51, 1)
+ ),
+ ),
+ SizedBox(
+ width: 204.w,
+ child: Text(
+ "优化了动画细节,让产品更流畅。",
+ style: TextStyle(
+ fontSize: 12.w,
+ ),
+ ),
+ )
+ ],
+ ),
+ SizedBox(height: 32.w,),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Container(
+ width: 113.w,
+ height: 40.w,
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.all(Radius.circular(9.w)),
+ color: const Color.fromRGBO(245, 245, 245, 1)
+ ),
+ child: Center(
+ child: Text(
+ "暂不更新",
+ style: TextStyle(
+ fontSize: 15.w,
+ color: const Color.fromRGBO(144, 144, 144, 1)
+ ),
+ ),
+ ),
+ ).onTap((){
+ Navigator.of(context).pop();
+ }),
+ Container(
+ width: 113.w,
+ height: 40.w,
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.all(Radius.circular(9.w)),
+ color: const Color.fromRGBO(245, 245, 245, 1),
+ gradient: const LinearGradient(
+ begin: Alignment.centerLeft,
+ end: Alignment.centerRight, // 对应 CSS 90deg
+ colors: [
+ Color.fromRGBO(131, 89, 255, 1), // rgba(131, 89, 255, 1)
+ Color.fromRGBO(61, 138, 224, 1), // rgba(61, 138, 224, 1)
+ ],
+ ),
+ ),
+ child: Center(
+ child: Text(
+ "立即升级",
+ style: TextStyle(
+ fontSize: 15.w,
+ fontWeight: FontWeight.w500,
+ color: Colors.white
+ ),
+ ),
+ ),
+ ),
+ ],
+ )
+ ],
+ ),
+ ),
+ Positioned(
+ left: 0,
+ top: -56.w,
+ child: Image.asset(
+ Assets.imagesUpdataBg,
+ width: 299.w,
+ ),
+ ),
+ Positioned(
+ left: 11.w,
+ top: -14.w,
+ child: Image.asset(
+ Assets.imagesUpdataIcon,
+ width: 36.w,
+ ),
+ ),
+ Positioned(
+ left: 43.w,
+ top: 29.w,
+ child: Image.asset(
+ Assets.imagesUpdataFont,
+ width: 76.w,
+ ),
+ )
+ ],
+ ),
+ ),
+ );
+ }));
+ }
+
+}
+
diff --git a/lib/main.dart b/lib/main.dart
index 265b61e..a89fe82 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -22,8 +22,8 @@ void main() async {
// 设置环境配置 - 根据是否为release模式
EnvConfig.setEnvironment(Environment.dev);
- RTCManager.instance.initialize(appId: '4c2ea9dcb4c5440593a418df0fdd512d');
- IMManager.instance.initialize('1165251016193374#demo');
+ await RTCManager.instance.initialize(appId: '4c2ea9dcb4c5440593a418df0fdd512d');
+ await IMManager.instance.initialize('1165251016193374#demo');
// 初始化全局依赖
final networkService = NetworkService();
Get.put(networkService);
@@ -84,10 +84,10 @@ class MyApp extends StatelessWidget {
// 判断token是否为空
final storage = GetStorage();
- final token = storage.read('token');
+ final userId = storage.read('userId');
// 如果token不为空,显示主页;如果token为空,显示登录页面
- if (token != null && token.isNotEmpty) {
+ if (userId != null && userId.isNotEmpty) {
return MainPage();
} else {
return LoginPage();
diff --git a/lib/model/mine/user_data.dart b/lib/model/mine/user_data.dart
index 65b50f3..d0cdd1c 100644
--- a/lib/model/mine/user_data.dart
+++ b/lib/model/mine/user_data.dart
@@ -1,11 +1,11 @@
// 用户详细信息实体类
class UserData {
- final String? id;
- final String? nickName;
+ String? id;
+ String? nickName;
final String? name;
- final String? profilePhoto;
+ String? profilePhoto;
String? identityCard;
- final int? genderCode;
+ int? genderCode;
final String? genderValue;
final String? homeCountryCode;
final String? homeCountry;
@@ -23,8 +23,8 @@ class UserData {
final String? chineseZodiac;
final int? height;
final int? weight;
- final int? educationCode;
- final String? education;
+ int? educationCode;
+ String? education;
final int? maritalStatusCode;
final String? maritalStatusName;
final int? minimumIncome;
diff --git a/lib/model/rtc/rtc_channel_data.dart b/lib/model/rtc/rtc_channel_data.dart
index 05c65e0..b5795c4 100644
--- a/lib/model/rtc/rtc_channel_data.dart
+++ b/lib/model/rtc/rtc_channel_data.dart
@@ -2,16 +2,19 @@
class RtcChannelData {
final String channelId;
final String token;
+ final int uid;
RtcChannelData({
required this.channelId,
required this.token,
+ required this.uid,
});
factory RtcChannelData.fromJson(Map json) {
return RtcChannelData(
channelId: json['channelId']?.toString() ?? '',
token: json['token']?.toString() ?? '',
+ uid: json['uid'] ?? 0,
);
}
@@ -19,6 +22,7 @@ class RtcChannelData {
return {
'channelId': channelId,
'token': token,
+ 'uid': uid,
};
}
diff --git a/lib/network/api_urls.dart b/lib/network/api_urls.dart
index d5336df..ea4e69b 100644
--- a/lib/network/api_urls.dart
+++ b/lib/network/api_urls.dart
@@ -23,7 +23,10 @@ class ApiUrls {
static const String getMaritalStatusList = 'dating-agency-service/user/get/marital/status/list';
static const String getPropertyList = 'dating-agency-service/user/get/property/permits';
static const String getOccupationList = 'dating-agency-service/user/get/occupation/list';
+ static const String getSwRtcToken = 'dating-agency-chat-audio/user/get/sw/rtc/token';
static const String createRtcChannel = 'dating-agency-chat-audio/user/create/rtc-channel';
+ static const String editOwnMarriageInformation = 'dating-agency-service/user/edit/own-marriage-information';
+ static const String getSwRtmToken = 'dating-agency-chat-audio/user/get/sw/rtm/token';
//首页相关接口
static const String getMarriageList = 'dating-agency-service/user/page/dongwo/marriage-information';
diff --git a/lib/network/network_config.dart b/lib/network/network_config.dart
index 58f0e53..c892bf5 100644
--- a/lib/network/network_config.dart
+++ b/lib/network/network_config.dart
@@ -83,7 +83,6 @@ class ResponseInterceptor extends Interceptor {
) {
// 统一处理响应数据
final data = response.data;
-
// 检查响应状态码
if (response.statusCode == 200) {
// 假设后端返回的数据格式为 {"code": 0, "message": "success", "data": {...}}
diff --git a/lib/network/rtc_api.dart b/lib/network/rtc_api.dart
index c298e3c..7e4c4e8 100644
--- a/lib/network/rtc_api.dart
+++ b/lib/network/rtc_api.dart
@@ -12,6 +12,14 @@ abstract class RtcApi {
factory RtcApi(Dio dio) = _RtcApi;
/// 创建实时音视频频道
+ @GET(ApiUrls.getSwRtcToken)
+ Future>> getSwRtcToken();
+
+ /// 获取声网 RTM Token
+ @GET(ApiUrls.getSwRtmToken)
+ Future>> getSwRtmToken();
+
+ /// 创建实时音视频频道(返回字符串)
@POST(ApiUrls.createRtcChannel)
Future>> createRtcChannel();
}
diff --git a/lib/network/rtc_api.g.dart b/lib/network/rtc_api.g.dart
index 528db3a..2cbdf56 100644
--- a/lib/network/rtc_api.g.dart
+++ b/lib/network/rtc_api.g.dart
@@ -19,6 +19,68 @@ class _RtcApi implements RtcApi {
final ParseErrorLogger? errorLogger;
+ @override
+ Future>> getSwRtcToken() async {
+ final _extra = {};
+ final queryParameters = {};
+ final _headers = {};
+ const Map? _data = null;
+ final _options = _setStreamType>>(
+ Options(method: 'GET', headers: _headers, extra: _extra)
+ .compose(
+ _dio.options,
+ 'dating-agency-chat-audio/user/get/sw/rtc/token',
+ queryParameters: queryParameters,
+ data: _data,
+ )
+ .copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
+ );
+ final _result = await _dio.fetch