diff --git a/.kotlin/errors/errors-1740038374254.log b/.kotlin/errors/errors-1740038374254.log new file mode 100644 index 0000000..1531ea7 --- /dev/null +++ b/.kotlin/errors/errors-1740038374254.log @@ -0,0 +1,82 @@ +kotlin version: 2.0.21 +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:195) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:128) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:170) + at org.gradle.internal.Factories$1.create(Factories.java:31) + at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:267) + at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:131) + at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:136) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:165) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:134) + 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.nio.file.DirectoryNotEmptyException: C:\Users\User\AppData\Local\Temp\kotlin-backups11164380389062662786 + at java.base/sun.nio.fs.WindowsFileSystemProvider.implDelete(Unknown Source) + at java.base/sun.nio.fs.AbstractFileSystemProvider.delete(Unknown Source) + at java.base/java.nio.file.Files.delete(Unknown Source) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction$cleanupStash$2$1$1.invoke(CompilationTransaction.kt:244) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction$cleanupStash$2$1$1.invoke(CompilationTransaction.kt:244) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction.cleanupStash$lambda$11$lambda$10$lambda$9(CompilationTransaction.kt:244) + at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Unknown Source) + at java.base/java.util.ArrayList.forEach(Unknown Source) + at java.base/java.util.stream.SortedOps$RefSortingSink.end(Unknown Source) + at java.base/java.util.stream.Sink$ChainedReference.end(Unknown Source) + at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source) + at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source) + at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source) + at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source) + at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source) + at java.base/java.util.stream.ReferencePipeline.forEach(Unknown Source) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction.cleanupStash(CompilationTransaction.kt:244) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction.close(CompilationTransaction.kt:254) + at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.tryCompileIncrementally(IncrementalCompilerRunner.kt:747) + at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compile(IncrementalCompilerRunner.kt:120) + at org.jetbrains.kotlin.daemon.CompileServiceImplBase.execIncrementalCompiler(CompileServiceImpl.kt:675) + at org.jetbrains.kotlin.daemon.CompileServiceImplBase.access$execIncrementalCompiler(CompileServiceImpl.kt:92) + at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1660) + 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 + + diff --git a/.kotlin/errors/errors-1740039190766.log b/.kotlin/errors/errors-1740039190766.log new file mode 100644 index 0000000..38660ba --- /dev/null +++ b/.kotlin/errors/errors-1740039190766.log @@ -0,0 +1,82 @@ +kotlin version: 2.0.21 +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:195) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:128) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:170) + at org.gradle.internal.Factories$1.create(Factories.java:31) + at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:267) + at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:131) + at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:136) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:165) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:134) + 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.nio.file.DirectoryNotEmptyException: C:\Users\User\AppData\Local\Temp\kotlin-backups8341820686666786180 + at java.base/sun.nio.fs.WindowsFileSystemProvider.implDelete(Unknown Source) + at java.base/sun.nio.fs.AbstractFileSystemProvider.delete(Unknown Source) + at java.base/java.nio.file.Files.delete(Unknown Source) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction$cleanupStash$2$1$1.invoke(CompilationTransaction.kt:244) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction$cleanupStash$2$1$1.invoke(CompilationTransaction.kt:244) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction.cleanupStash$lambda$11$lambda$10$lambda$9(CompilationTransaction.kt:244) + at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Unknown Source) + at java.base/java.util.ArrayList.forEach(Unknown Source) + at java.base/java.util.stream.SortedOps$RefSortingSink.end(Unknown Source) + at java.base/java.util.stream.Sink$ChainedReference.end(Unknown Source) + at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source) + at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source) + at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source) + at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source) + at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source) + at java.base/java.util.stream.ReferencePipeline.forEach(Unknown Source) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction.cleanupStash(CompilationTransaction.kt:244) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction.close(CompilationTransaction.kt:254) + at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.tryCompileIncrementally(IncrementalCompilerRunner.kt:747) + at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compile(IncrementalCompilerRunner.kt:120) + at org.jetbrains.kotlin.daemon.CompileServiceImplBase.execIncrementalCompiler(CompileServiceImpl.kt:675) + at org.jetbrains.kotlin.daemon.CompileServiceImplBase.access$execIncrementalCompiler(CompileServiceImpl.kt:92) + at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1660) + 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 + + diff --git a/.kotlin/errors/errors-1740053232762.log b/.kotlin/errors/errors-1740053232762.log new file mode 100644 index 0000000..51f29bd --- /dev/null +++ b/.kotlin/errors/errors-1740053232762.log @@ -0,0 +1,82 @@ +kotlin version: 2.0.21 +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:195) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:128) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:170) + at org.gradle.internal.Factories$1.create(Factories.java:31) + at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:267) + at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:131) + at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:136) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:165) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:134) + 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.nio.file.DirectoryNotEmptyException: C:\Users\User\AppData\Local\Temp\kotlin-backups1146231745401124119 + at java.base/sun.nio.fs.WindowsFileSystemProvider.implDelete(Unknown Source) + at java.base/sun.nio.fs.AbstractFileSystemProvider.delete(Unknown Source) + at java.base/java.nio.file.Files.delete(Unknown Source) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction$cleanupStash$2$1$1.invoke(CompilationTransaction.kt:244) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction$cleanupStash$2$1$1.invoke(CompilationTransaction.kt:244) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction.cleanupStash$lambda$11$lambda$10$lambda$9(CompilationTransaction.kt:244) + at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Unknown Source) + at java.base/java.util.ArrayList.forEach(Unknown Source) + at java.base/java.util.stream.SortedOps$RefSortingSink.end(Unknown Source) + at java.base/java.util.stream.Sink$ChainedReference.end(Unknown Source) + at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source) + at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source) + at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source) + at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source) + at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source) + at java.base/java.util.stream.ReferencePipeline.forEach(Unknown Source) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction.cleanupStash(CompilationTransaction.kt:244) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction.close(CompilationTransaction.kt:254) + at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.tryCompileIncrementally(IncrementalCompilerRunner.kt:747) + at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compile(IncrementalCompilerRunner.kt:120) + at org.jetbrains.kotlin.daemon.CompileServiceImplBase.execIncrementalCompiler(CompileServiceImpl.kt:675) + at org.jetbrains.kotlin.daemon.CompileServiceImplBase.access$execIncrementalCompiler(CompileServiceImpl.kt:92) + at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1660) + 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 + + diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b0bfb57..23a69ca 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,9 +1,9 @@ plugins { - kotlinAndroid - androidApplication - jetbrainsKotlinSerialization version Version.Kotlin.language - kotlinAnnotationProcessor - id("com.google.dagger.hilt.android").version("2.51.1") + id("com.android.application") + id("kotlin-android") + id("kotlin-kapt") // Добавлено для KAPT + id("dagger.hilt.android.plugin") // Используйте этот синтаксис для Hilt + id("org.jetbrains.kotlin.plugin.serialization") version Version.Kotlin.language // Убедитесь, что версия актуальна } val packageName = "ru.myitschool.work" @@ -22,9 +22,9 @@ android { testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } - buildFeatures.viewBinding = true - - + buildFeatures { + viewBinding = true + } compileOptions { sourceCompatibility = Version.Kotlin.javaSource @@ -37,38 +37,41 @@ android { } dependencies { - implementation ("com.squareup.retrofit2:retrofit:2.9.0") - implementation ("com.squareup.retrofit2:converter-gson:2.9.0") - implementation ("com.squareup.okhttp3:okhttp:4.9.0") - implementation ("com.github.bumptech.glide:glide:4.15.1") + // Retrofit and OkHttp + implementation("com.squareup.retrofit2:retrofit:2.9.0") + implementation("com.squareup.retrofit2:converter-gson:2.9.0") + implementation("com.squareup.okhttp3:okhttp:4.9.0") + + // Glide + implementation("com.github.bumptech.glide:glide:4.15.1") + kapt("com.github.bumptech.glide:compiler:4.15.1") + + // AndroidX Libraries implementation("androidx.appcompat:appcompat:1.6.1") implementation("com.google.android.material:material:1.10.0") implementation("androidx.activity:activity:1.10.0") implementation("androidx.constraintlayout:constraintlayout:2.1.4") - kapt ("com.github.bumptech.glide:compiler:4.15.1") - - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0") - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0") implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.5.1") - defaultLibrary() + // Coroutines + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0") - implementation(Dependencies.AndroidX.activity) - implementation(Dependencies.AndroidX.fragment) - implementation(Dependencies.AndroidX.constraintLayout) + // Hilt dependencies + implementation("com.google.dagger:hilt-android:2.51.1") + kapt("com.google.dagger:hilt-android-compiler:2.51.1") + // Navigation implementation(Dependencies.AndroidX.Navigation.fragment) implementation(Dependencies.AndroidX.Navigation.navigationUi) - implementation(Dependencies.Retrofit.library) - implementation(Dependencies.Retrofit.gsonConverter) - - - implementation("com.squareup.picasso:picasso:2.8") - implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.1") + // DataStore implementation("androidx.datastore:datastore-preferences:1.1.1") + + // ML Kit implementation("com.google.mlkit:barcode-scanning:17.3.0") + // CameraX val cameraX = "1.3.4" implementation("androidx.camera:camera-core:$cameraX") implementation("androidx.camera:camera-camera2:$cameraX") @@ -76,11 +79,13 @@ dependencies { implementation("androidx.camera:camera-view:$cameraX") implementation("androidx.camera:camera-mlkit-vision:1.4.0-rc04") - val hilt = "2.51.1" - implementation("com.google.dagger:hilt-android:$hilt") - kapt("com.google.dagger:hilt-android-compiler:$hilt") + // Picasso + implementation("com.squareup.picasso:picasso:2.8") + + // Kotlin Serialization + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.1") } kapt { correctErrorTypes = true -} +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2a9c5ce..0dd787c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -33,6 +33,7 @@ + \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/App.kt b/app/src/main/java/ru/myitschool/work/App.kt index 3085135..0b0dbf7 100644 --- a/app/src/main/java/ru/myitschool/work/App.kt +++ b/app/src/main/java/ru/myitschool/work/App.kt @@ -4,4 +4,9 @@ import android.app.Application import dagger.hilt.android.HiltAndroidApp @HiltAndroidApp -class App : Application() \ No newline at end of file +class App : Application() { + override fun onCreate() { + super.onCreate() + SessionManager.init(this) // Инициализация SessionManager + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/SessionManager.kt b/app/src/main/java/ru/myitschool/work/SessionManager.kt index 4f43031..fcb9b40 100644 --- a/app/src/main/java/ru/myitschool/work/SessionManager.kt +++ b/app/src/main/java/ru/myitschool/work/SessionManager.kt @@ -1,10 +1,39 @@ package ru.myitschool.work -object SessionManager { - var userLogin: String? = null // Логин пользователя - var userRole: String? = null // Роль пользователя +import android.content.Context +import android.content.SharedPreferences +import java.util.Base64 + +object SessionManager { + private const val PREF_NAME = "user_session" + private const val KEY_USER_LOGIN = "user_login" + private const val KEY_USER_ROLE = "user_role" + + private lateinit var preferences: SharedPreferences + + fun init(context: Context) { + preferences = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) + } + + var userLogin: String? + get() = preferences.getString(KEY_USER_LOGIN, null) + set(value) { + preferences.edit().putString(KEY_USER_LOGIN, value).apply() + } + + var userRole: String? + get() = preferences.getString(KEY_USER_ROLE, null) + set(value) { + preferences.edit().putString(KEY_USER_ROLE, value).apply() + } + + fun getAuthHeader(): String { + val username = userLogin ?: return "" + val password = "password123" // Замените на ваш пароль + val credential = Base64.getEncoder().encodeToString("$username:$password".toByteArray()) + return "Basic $credential" + } - // Метод для очистки данных сессии fun clearSession() { userLogin = null userRole = null diff --git a/app/src/main/java/ru/myitschool/work/api/ApiModule.kt b/app/src/main/java/ru/myitschool/work/api/ApiModule.kt index 1b02705..9f0fb34 100644 --- a/app/src/main/java/ru/myitschool/work/api/ApiModule.kt +++ b/app/src/main/java/ru/myitschool/work/api/ApiModule.kt @@ -1,5 +1,6 @@ package ru.myitschool.work.api +import LoggingInterceptor import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -7,7 +8,6 @@ import dagger.hilt.components.SingletonComponent import okhttp3.OkHttpClient import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory -import ru.myitschool.work.core.Constants import javax.inject.Singleton @Module @@ -16,19 +16,26 @@ object ApiModule { @Provides @Singleton - fun provideOkHttpClient(): OkHttpClient { + fun provideOkHttpClient(authInterceptor: AuthInterceptor): OkHttpClient { + return OkHttpClient.Builder() + .addInterceptor(authInterceptor) // Добавляем интерсептор аутентификации + .addInterceptor(LoggingInterceptor()) // Добавляем интерсептор логирования + .build() + } + + @Provides + @Singleton + fun provideAuthInterceptor(): AuthInterceptor { val username = "pivanov" // Замените на ваш логин val password = "password123" // Замените на ваш пароль - return OkHttpClient.Builder() - .addInterceptor(AuthInterceptor(username, password)) - .build() + return AuthInterceptor(username, password) } @Provides @Singleton fun provideRetrofit(client: OkHttpClient): Retrofit { return Retrofit.Builder() - .baseUrl(Constants.SERVER_ADDRESS) + .baseUrl("http://10.6.66.110:8080/") // Убедитесь, что URL корректен .client(client) .addConverterFactory(GsonConverterFactory.create()) .build() diff --git a/app/src/main/java/ru/myitschool/work/api/ApiService.kt b/app/src/main/java/ru/myitschool/work/api/ApiService.kt index cd239ad..9c1480f 100644 --- a/app/src/main/java/ru/myitschool/work/api/ApiService.kt +++ b/app/src/main/java/ru/myitschool/work/api/ApiService.kt @@ -3,6 +3,7 @@ package ru.myitschool.work.api import retrofit2.Response import retrofit2.http.Body import retrofit2.http.GET +import retrofit2.http.Header import retrofit2.http.PATCH import retrofit2.http.POST import retrofit2.http.Path @@ -10,21 +11,26 @@ import retrofit2.http.Query interface ApiService { // Метод для аутентификации - @GET("/api/auth") // Используем GET для аутентификации + @GET("/api/auth") suspend fun authenticate( - @Query("login") login: String, // Передаем логин как параметр запроса - @Query("password") password: String // Передаем пароль как параметр запроса - ): Response // Возвращаем JSON как объект UserAuthResponse + @Query("login") login: String, + @Query("password") password: String + ): Response // Измените Response на Response - // Другие методы... - @GET("/api/{login}/info") // Получение информации о пользователе - suspend fun getUserInfo(@Path("login") login: String): Response> + @GET("/api/{login}/info") + suspend fun getUserInfo( + @Path("login") login: String, + @Header("Authorization") authHeader: String + ): Response @GET("/api/employee/{login}") // Получение информации о сотруднике suspend fun getEmployeeInfo(@Path("login") login: String): Response @PATCH("/api/open") // Открыть дверь - suspend fun openDoor(@Body request: OpenDoorRequest): Response + suspend fun openDoor( + @Header("Authorization") authHeader: String, + @Body request: OpenDoorRequest + ): Response // Измените Response на Response @POST("/api/employee/toggleAccess") // Метод для блокировки/разблокировки доступа suspend fun toggleAccess(@Body request: ToggleAccessRequest): Response @@ -33,16 +39,12 @@ interface ApiService { suspend fun getAllWorkers(): Response> } -// Модель данных для ответа аутентификации -data class UserAuthResponse( - val role: String // Добавляем поле для роли -) - // Модель данных для информации о сотруднике data class EmployeeData( val name: String, val position: String, - val lastVisit: String + val lastVisit: String, + val avatarUrl: String? // Добавьте это поле ) // Модель данных для запроса блокировки/разблокировки доступа @@ -53,6 +55,5 @@ data class ToggleAccessRequest( // Модель данных для запроса открытия двери data class OpenDoorRequest( - val login: String, // Логин сотрудника val value: Long // Код для открытия двери ) \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/api/LoginInterceptor.kt b/app/src/main/java/ru/myitschool/work/api/LoginInterceptor.kt new file mode 100644 index 0000000..ffc7c5c --- /dev/null +++ b/app/src/main/java/ru/myitschool/work/api/LoginInterceptor.kt @@ -0,0 +1,15 @@ +import okhttp3.Interceptor +import okhttp3.Response +import android.util.Log + +class LoggingInterceptor : Interceptor { + override fun intercept(chain: Interceptor.Chain): Response { + val request = chain.request() + Log.d("LoggingInterceptor", "Sending request to ${request.url} with headers ${request.headers}") + + val response = chain.proceed(request) + + Log.d("LoggingInterceptor", "Received response for ${response.request.url} with code ${response.code}") + return response + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/core/Constants.kt b/app/src/main/java/ru/myitschool/work/core/Constants.kt index 63a66e1..433902f 100644 --- a/app/src/main/java/ru/myitschool/work/core/Constants.kt +++ b/app/src/main/java/ru/myitschool/work/core/Constants.kt @@ -2,4 +2,5 @@ package ru.myitschool.work.core // БЕРИТЕ И ИЗМЕНЯЙТЕ ХОСТ ТОЛЬКО ЗДЕСЬ И НЕ БЕРИТЕ ИЗ ДРУГИХ МЕСТ. ФАЙЛ ПЕРЕМЕЩАТЬ НЕЛЬЗЯ object Constants { const val SERVER_ADDRESS = "http://10.6.66.110:8080" + //, } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/Main/AdminFragment.kt b/app/src/main/java/ru/myitschool/work/ui/Main/AdminFragment.kt index 5ca0578..5fe797f 100644 --- a/app/src/main/java/ru/myitschool/work/ui/Main/AdminFragment.kt +++ b/app/src/main/java/ru/myitschool/work/ui/Main/AdminFragment.kt @@ -1,4 +1,4 @@ -package ru.myitschool.work.ui.Main +package ru.myitschool.work.ui.main import android.os.Bundle import android.view.View @@ -10,7 +10,6 @@ import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory import ru.myitschool.work.R import ru.myitschool.work.api.ApiService -import ru.myitschool.work.api.EmployeeData import ru.myitschool.work.api.ToggleAccessRequest import ru.myitschool.work.core.Constants import ru.myitschool.work.databinding.FragmentAdminBinding diff --git a/app/src/main/java/ru/myitschool/work/ui/Main/MainFragment.kt b/app/src/main/java/ru/myitschool/work/ui/Main/MainFragment.kt index 1524b9c..6a1096f 100644 --- a/app/src/main/java/ru/myitschool/work/ui/Main/MainFragment.kt +++ b/app/src/main/java/ru/myitschool/work/ui/Main/MainFragment.kt @@ -1,201 +1,144 @@ package ru.myitschool.work.ui.main -import android.graphics.Bitmap -import android.graphics.BitmapFactory import android.os.Bundle +import android.util.Log import android.view.View import android.widget.Toast import androidx.fragment.app.Fragment import androidx.fragment.app.setFragmentResultListener import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController -import androidx.recyclerview.widget.LinearLayoutManager -import kotlinx.coroutines.Dispatchers +import com.squareup.picasso.Picasso import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import retrofit2.Retrofit -import retrofit2.converter.gson.GsonConverterFactory import ru.myitschool.work.R -import ru.myitschool.work.SessionManager -import ru.myitschool.work.api.AccessLog import ru.myitschool.work.api.ApiService +import ru.myitschool.work.api.EmployeeData import ru.myitschool.work.core.Constants import ru.myitschool.work.databinding.FragmentMainBinding +import ru.myitschool.work.SessionManager +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory import ru.myitschool.work.ui.qr.scan.QrScanDestination -import java.net.HttpURLConnection -import java.net.URL class MainFragment : Fragment(R.layout.fragment_main) { private var _binding: FragmentMainBinding? = null private val binding get() = _binding!! - private val apiService: ApiService by lazy { - Retrofit.Builder() + private lateinit var apiService: ApiService + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + apiService = Retrofit.Builder() .baseUrl(Constants.SERVER_ADDRESS) .addConverterFactory(GsonConverterFactory.create()) .build() .create(ApiService::class.java) } - private lateinit var accessLogAdapter: AccessLogAdapter - private val accessLogs = mutableListOf() // Список для хранения данных проходов - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - _binding = FragmentMainBinding.bind(view) // Подключаем binding + _binding = FragmentMainBinding.bind(view) setupUI() - fetchUserData() - checkAdminAccess() // Проверяем доступ администратора + fetchUserInfo() // Проверяем, есть ли результат QR checkQrResult() } - private fun checkAdminAccess() { - // Проверяем, является ли пользователь администратором - if (SessionManager.userRole == "admin") { - binding.adminPanel.visibility = View.VISIBLE // Показываем кнопку AdminPanel - binding.adminPanel.setOnClickListener { - findNavController().navigate(R.id.adminFragment) // Переход на экран администратора - } - } else { - binding.adminPanel.visibility = View.GONE // Скрываем кнопку для обычных пользователей - } - } - private fun checkQrResult() { // Слушаем результат QR сканирования setFragmentResultListener(QrScanDestination.REQUEST_KEY) { _, bundle -> val qrData = QrScanDestination.getDataIfExist(bundle) if (qrData != null) { // Если данные QR есть, переходим на экран с результатом - findNavController().navigate(R.id.qrResultFragment) + val resultBundle = QrScanDestination.packToBundle(qrData) + findNavController().navigate(R.id.qrResultFragment, resultBundle) + } else { + Toast.makeText(requireContext(), "QR данные не найдены", Toast.LENGTH_SHORT).show() } } } private fun setupUI() { - // Настройка RecyclerView - binding.recyclerView.layoutManager = LinearLayoutManager(requireContext()) - accessLogAdapter = AccessLogAdapter(accessLogs) - binding.recyclerView.adapter = accessLogAdapter + binding.refresh.setOnClickListener { + fetchUserInfo() + } - // Проверяем, что binding не null, прежде чем устанавливать слушателей - binding.apply { - refresh.setOnClickListener { fetchUserData() } - logout.setOnClickListener { logout() } - scan.setOnClickListener { navigateToQrScan() } + binding.scanQrCode?.setOnClickListener { + // Переход к экрану сканирования QR-кода + findNavController().navigate(R.id.qrScanFragment) // Убедитесь, что у вас есть правильный ID для навигации + } + + // Проверяем роль пользователя и показываем кнопку AdminPanel, если роль admin + if (SessionManager.userRole == "admin") { + binding.adminPanelButton?.visibility = View.VISIBLE + binding.adminPanelButton?.setOnClickListener { + findNavController().navigate(R.id.adminFragment) // Переход к экрану администратора + } + } else { + binding.adminPanelButton?.visibility = View.GONE // Скрываем кнопку, если не admin } } - private fun fetchUserData() { + private fun fetchUserInfo() { lifecycleScope.launch { - showError(null) // Скрыть ошибку, если она была + val login = SessionManager.userLogin ?: run { + binding.error.text = "Пользователь не авторизован" + binding.error.visibility = View.VISIBLE + return@launch + } + val authHeader = SessionManager.getAuthHeader() ?: run { + binding.error.text = "Ошибка авторизации" + binding.error.visibility = View.VISIBLE + return@launch + } + try { - val response = - SessionManager.userLogin?.let { apiService.getUserInfo(it) } // Получаем данные пользователя - if (response != null) { - if (response.isSuccessful) { - response.body()?.let { data -> - // Извлекаем значения из Map - val fullName = data["name"] as? String ?: "Неизвестно" - val position = data["position"] as? String ?: "Неизвестно" - val lastVisit = data["lastVisit"] as? String ?: "Неизвестно" - val photoUrl = data["photo"] as? String ?: "" + val response = apiService.getUserInfo(login, authHeader) - // Обновляем UI - updateUI(fullName, position, lastVisit, photoUrl) + // Логируем код ответа + Log.d("MainFragment", "Response code: ${response.code()}") - // Здесь вы можете добавить данные проходов в список - // Пример: - accessLogs.add(AccessLog("2024-02-31 08:31", "Считыватель 1", "карта")) - accessLogAdapter.notifyDataSetChanged() // Обновляем адаптер + if (response.isSuccessful) { + val employeeData = response.body() + employeeData?.let { + binding.fullname.text = it.name + binding.position.text = it.position + binding.lastEntry.text = it.lastVisit + + // Логируем URL аватара + Log.d("MainFragment", "Avatar URL: ${it.avatarUrl}") + + // Загрузка аватара с помощью Picasso + if (it.avatarUrl != null) { + Picasso.get() + .load(it.avatarUrl) + .placeholder(R.drawable.ic_refresh) // Замените на ваш ресурс-заполнитель + .error(R.drawable.ic_close) // Замените на ваш ресурс ошибки + .into(binding.photo) + binding.photo.visibility = View.VISIBLE + } else { + binding.photo.visibility = View.GONE // Скрыть, если URL нет } - } else { - showError(getString(R.string.error_loading_data)) // Показываем ошибку, если данные не загрузились + + // Показываем кнопку "Сканировать QR-код" после успешного получения данных + binding.scanQrCode?.visibility = View.VISIBLE } + } else { + binding.error.text = "Ошибка получения данных: ${response.message()}" + binding.error.visibility = View.VISIBLE } } catch (e: Exception) { - showError(e.localizedMessage) // Показываем ошибку при исключении + Log.e("MainFragment", "Error fetching user info", e) + binding.error.text = "Ошибка сети: ${e.message}" + binding.error.visibility = View.VISIBLE } } } - private fun updateUI(fullName: String, position1: String, lastVisit: String, photoUrl: String) { - // Проверяем, что binding не null, прежде чем обновлять UI - binding?.apply { - fullname.text = fullName - position.text = position1 - lastEntry.text = lastVisit - if (photoUrl.isNotEmpty()) { - // Загружаем изображение - lifecycleScope.launch { - val bitmap = loadImageFromUrl(photoUrl) - bitmap?.let { photo.setImageBitmap(it) } - } - } - - // Показываем элементы - fullname.visibility = View.VISIBLE - position.visibility = View.VISIBLE - lastEntry.visibility = View.VISIBLE - photo.visibility = View.VISIBLE - logout.visibility = View.VISIBLE - scan.visibility = View.VISIBLE - } - } - - private suspend fun loadImageFromUrl(urlString: String): Bitmap? { - return withContext(Dispatchers.IO) { - try { - val url = URL(urlString) - val connection = url.openConnection() as HttpURLConnection - connection.doInput = true - connection.connect() - val inputStream = connection.inputStream - BitmapFactory.decodeStream(inputStream) - } catch (e: Exception) { - e.printStackTrace() - null - } - } - } - - private fun showError(message: String?) { - // Проверяем, что binding не null, прежде чем обновлять ошибку - binding.apply { - if (message != null) { - error.text = message - error.visibility = View.VISIBLE - - // Скрываем остальные элементы, когда возникает ошибка - fullname.visibility = View.GONE - position.visibility = View.GONE - lastEntry.visibility = View.GONE - photo.visibility = View.GONE - logout.visibility = View.GONE - scan.visibility = View.GONE - recyclerView.visibility = View.GONE // Скрываем RecyclerView при ошибке - } else { - error.visibility = View.GONE - recyclerView.visibility = View.VISIBLE // Показываем RecyclerView, если ошибки нет - } - } - } - - private fun logout() { - // Очистите данные пользователя - Toast.makeText(requireContext(), getString(R.string.logged_out), Toast.LENGTH_SHORT).show() - findNavController().navigate(R.id.loginFragment) // Переход на экран входа - } - - private fun navigateToQrScan() { - findNavController().navigate(R.id.qrScanFragment) // Переход на экран сканирования QR - } - override fun onDestroyView() { - _binding = null // Освобождаем binding, когда представление уничтожается + _binding = null super.onDestroyView() } } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/Main/MainViewModel.kt b/app/src/main/java/ru/myitschool/work/ui/Main/MainViewModel.kt index e18e24a..3fb2ad1 100644 --- a/app/src/main/java/ru/myitschool/work/ui/Main/MainViewModel.kt +++ b/app/src/main/java/ru/myitschool/work/ui/Main/MainViewModel.kt @@ -1,47 +1,39 @@ package ru.myitschool.work.ui.main +import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch -import ru.myitschool.work.SessionManager import ru.myitschool.work.api.ApiService +import ru.myitschool.work.api.EmployeeData import javax.inject.Inject @HiltViewModel class MainViewModel @Inject constructor( private val apiService: ApiService ) : ViewModel() { - private val _userInfoState = MutableStateFlow?>(null) - val userInfoState: StateFlow?> = _userInfoState - init { - loadUserData() - } + private val _employeeData = MutableStateFlow(null) + val employeeData: StateFlow get() = _employeeData - private fun loadUserData() { + private val _errorMessage = MutableStateFlow(null) + val errorMessage: StateFlow get() = _errorMessage + + fun fetchUserInfo(login: String, authHeader: String) { viewModelScope.launch { try { - val login = SessionManager.userLogin - if (login != null) { - val response = apiService.getUserInfo(login) - if (response.isSuccessful) { - _userInfoState.value = response.body() - } else { - // Обработка ошибки, если ответ не успешен - _userInfoState.value = null // Или установите какое-то состояние ошибки - } + val response = apiService.getUserInfo(login, authHeader) + if (response.isSuccessful) { + _employeeData.value = response.body() } else { - // Логин равен null, обработайте это состояние - _userInfoState.value = null // Или установите какое-то состояние ошибки + _errorMessage.value = "Ошибка получения данных: ${response.message()}" } } catch (e: Exception) { - // Логирование ошибки - e.printStackTrace() - // Установите состояние ошибки - _userInfoState.value = null // Или установите какое-то состояние ошибки + Log.e("MainViewModel", "Error fetching user info", e) + _errorMessage.value = "Ошибка сети: ${e.message}" } } } diff --git a/app/src/main/java/ru/myitschool/work/ui/RootActivity.kt b/app/src/main/java/ru/myitschool/work/ui/RootActivity.kt index 1450ae5..e1a2ff1 100644 --- a/app/src/main/java/ru/myitschool/work/ui/RootActivity.kt +++ b/app/src/main/java/ru/myitschool/work/ui/RootActivity.kt @@ -44,4 +44,4 @@ class RootActivity : AppCompatActivity() { } return popBackResult || super.onSupportNavigateUp() } -} +} \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/login/LoginFragment.kt b/app/src/main/java/ru/myitschool/work/ui/login/LoginFragment.kt index 5d79f87..c6daf17 100644 --- a/app/src/main/java/ru/myitschool/work/ui/login/LoginFragment.kt +++ b/app/src/main/java/ru/myitschool/work/ui/login/LoginFragment.kt @@ -1,5 +1,6 @@ package ru.myitschool.work.ui.login +import ru.myitschool.work.api.ApiService import android.os.Bundle import android.text.Editable import android.text.InputType @@ -15,7 +16,6 @@ import androidx.navigation.fragment.findNavController import dagger.hilt.android.AndroidEntryPoint import ru.myitschool.work.R import ru.myitschool.work.SessionManager -import ru.myitschool.work.api.UserAuthResponse import ru.myitschool.work.databinding.FragmentLoginBinding import ru.myitschool.work.utils.collectWhenStarted import ru.myitschool.work.utils.visibleOrGone @@ -40,7 +40,7 @@ class LoginFragment : Fragment(R.layout.fragment_login) { } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) + super.onViewCreated(view, savedInstanceState) // Убедитесь, что этот вызов находится здесь _binding = FragmentLoginBinding.bind(view) setupUI() @@ -96,12 +96,6 @@ class LoginFragment : Fragment(R.layout.fragment_login) { authPreferences.saveLoginState(true) authPreferences.saveLogin(binding.username.text.toString()) // Сохраняем логин - // Сохраняем роль пользователя в SessionManager - val userAuthResponse: UserAuthResponse? = state.userAuthResponse - userAuthResponse?.let { - SessionManager.userRole = it.role // Сохраняем роль - } - Toast.makeText(context, "Авторизация прошла успешно", Toast.LENGTH_SHORT).show() navigateToMainScreen() // Перенаправление на следующий экран } else if (state.error != null) { diff --git a/app/src/main/java/ru/myitschool/work/ui/login/LoginViewModel.kt b/app/src/main/java/ru/myitschool/work/ui/login/LoginViewModel.kt index 25dcb8a..15fc52d 100644 --- a/app/src/main/java/ru/myitschool/work/ui/login/LoginViewModel.kt +++ b/app/src/main/java/ru/myitschool/work/ui/login/LoginViewModel.kt @@ -1,5 +1,6 @@ package ru.myitschool.work.ui.login +import ru.myitschool.work.api.ApiService import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope @@ -8,8 +9,6 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch import ru.myitschool.work.SessionManager -import ru.myitschool.work.api.ApiService -import ru.myitschool.work.api.UserAuthResponse import javax.inject.Inject @HiltViewModel @@ -21,34 +20,40 @@ class LoginViewModel @Inject constructor( val state: StateFlow get() = _state fun authenticate(username: String, password: String) { + Log.d("LoginViewModel", "Authenticating user: $username") // Логируем начало аутентификации + if (isValidUsername(username)) { viewModelScope.launch { try { + Log.d("LoginViewModel", "Sending authentication request to server") // Логируем отправку запроса val response = apiService.authenticate(username, password) - Log.d("LoginViewModel", "Response code: ${response.code()}") + Log.d("LoginViewModel", "Response code: ${response.code()}") // Логируем код ответа - if (response.isSuccessful) { - val userAuthResponse = response.body() // Получаем JSON-ответ - Log.d("LoginViewModel", "User Auth Response: $userAuthResponse") // Логируем ответ - - // Обработка JSON-ответа - if (userAuthResponse != null) { + // Проверяем код ответа + when (response.code()) { + 200 -> { SessionManager.userLogin = username - SessionManager.userRole = userAuthResponse.role // Сохраняем роль _state.value = LoginState(success = true) // Успешная авторизация - } else { - _state.value = LoginState(error = "Ошибка авторизации: Неверные учетные данные.") + Log.d("LoginViewModel", "Authentication successful") // Логируем успешную аутентификацию + } + 400 -> { + _state.value = LoginState(error = "Ошибка авторизации: Неверные учетные данные.") + Log.d("LoginViewModel", "Authentication failed: Invalid credentials") // Логируем ошибку + } + else -> { + _state.value = LoginState(error = "Ошибка авторизации: ${response.message()}") + Log.d("LoginViewModel", "Authentication failed: ${response.message()}") // Логируем ошибку } - } else { - _state.value = LoginState(error = "Ошибка авторизации: ${response.message()}") } } catch (e: Exception) { e.printStackTrace() _state.value = LoginState(error = "Ошибка сети. Проверьте подключение к интернету.") + Log.e("LoginViewModel", "Network error: ${e.message}") // Логируем ошибку сети } } } else { _state.value = LoginState(error = "Неправильный логин") + Log.d("LoginViewModel", "Invalid username: $username") // Логируем неправильный логин } } @@ -60,7 +65,6 @@ class LoginViewModel @Inject constructor( // Состояние аутентификации data class LoginState( val success: Boolean = false, // Успешность аутентификации - val userAuthResponse: UserAuthResponse? = null, // Ответ с информацией о пользователе val error: String? = null, // Сообщение об ошибке val maintenance: Boolean = false // Состояние техобслуживания ) \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/qr/result/QrResult.kt b/app/src/main/java/ru/myitschool/work/ui/qr/result/QrResult.kt index 327e9ad..9abef26 100644 --- a/app/src/main/java/ru/myitschool/work/ui/qr/result/QrResult.kt +++ b/app/src/main/java/ru/myitschool/work/ui/qr/result/QrResult.kt @@ -5,8 +5,10 @@ import androidx.navigation.fragment.findNavController import ru.myitschool.work.SessionManager import ru.myitschool.work.api.OpenDoorRequest import android.os.Bundle +import android.util.Log import android.view.LayoutInflater import android.view.View +import android.util.Base64 import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope @@ -19,7 +21,9 @@ import ru.myitschool.work.core.Constants import ru.myitschool.work.databinding.FragmentQrScanResultBinding class QrResult : Fragment(R.layout.fragment_qr_scan_result) { - private lateinit var binding: FragmentQrScanResultBinding + private var _binding: FragmentQrScanResultBinding? = null + private val binding get() = _binding!! + private lateinit var apiService: ApiService override fun onCreateView( @@ -27,7 +31,7 @@ class QrResult : Fragment(R.layout.fragment_qr_scan_result) { container: ViewGroup?, savedInstanceState: Bundle? ): View { - binding = FragmentQrScanResultBinding.inflate(inflater, container, false) + _binding = FragmentQrScanResultBinding.inflate(inflater, container, false) apiService = Retrofit.Builder() .baseUrl(Constants.SERVER_ADDRESS) .addConverterFactory(GsonConverterFactory.create()) @@ -40,8 +44,12 @@ class QrResult : Fragment(R.layout.fragment_qr_scan_result) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + // Получаем данные из аргументов val qrData = QrScanDestination.getDataIfExist(requireArguments()) + Log.d("QrResult", "QR Data: $qrData") // Логируем полученные данные + if (qrData != null) { + binding.result.text = "Результат сканирования: $qrData" // Отображаем результат сканирования sendRequestToServer(qrData) } else { binding.result.text = "Вход был отменён/Operation was cancelled" @@ -55,23 +63,40 @@ class QrResult : Fragment(R.layout.fragment_qr_scan_result) { private fun sendRequestToServer(qrData: String) { lifecycleScope.launch { try { - // Проверяем, что userLogin не равен null - val login = SessionManager.userLogin - if (login != null) { - // Создаем объект OpenDoorRequest с логином и кодом - val openDoorRequest = OpenDoorRequest(login, qrData.toLong()) // Преобразуем qrData в Long, если это необходимо - val response = apiService.openDoor(openDoorRequest) // Теперь передаем только openDoorRequest - if (response.isSuccessful) { - binding.result.text = "Успешно/Success" - } else { - binding.result.text = "Что-то пошло не так/Something wrong" - } + val qrValue = qrData.toLong() // Преобразуем данные QR-кода в Long + val login = SessionManager.userLogin ?: "default_login" // Замените на ваш логин + val password = "your_password" // Замените на ваш пароль + val authHeader = "Basic " + Base64.encodeToString("$login:$password".toByteArray(), Base64.NO_WRAP) + + // Логируем данные перед отправкой + Log.d("QrResult", "Sending request with QR value: $qrValue and authHeader: $authHeader") + + // Создаем объект запроса + val request = OpenDoorRequest(qrValue) + + // Вызываем метод openDoor с правильными параметрами + val response = apiService.openDoor(authHeader, request) + + // Логируем код ответа и тело ответа + Log.d("QrResult", "Response code: ${response.code()}") + Log.d("QrResult", "Response body: ${response.body()}") + + if (response.isSuccessful) { + binding.result.text = "Door Opened" // Сообщение о том, что дверь открыта } else { - binding.result.text = "Пользователь не авторизован/Unauthorized user" + binding.result.text = "Door Closed" // Сообщение о том, что дверь закрыта } + } catch (e: NumberFormatException) { + binding.result.text = "Некорректные данные QR-кода" } catch (e: Exception) { - binding.result.text = "Что-то пошло не так/Something wrong" + binding.result.text = "Что-то пошло не так/Something went wrong: ${e.message}" + Log.e("QrResult", "Error sending request to server", e) } } } + + override fun onDestroyView() { + _binding = null + super.onDestroyView() + } } \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml index ebc6847..bf6dee8 100644 --- a/app/src/main/res/layout/fragment_main.xml +++ b/app/src/main/res/layout/fragment_main.xml @@ -1,110 +1,65 @@ + android:padding="16dp"> - + android:textSize="18sp" /> - + android:contentDescription="@string/photo_description" /> - + android:textSize="16sp" /> - + android:textSize="14sp" /> -