From 2bcdd81eeb61848bf5754d79a2a530ced8aa0ee7 Mon Sep 17 00:00:00 2001 From: death-claw <53543762+death-claw@users.noreply.github.com> Date: Wed, 25 Dec 2024 16:23:13 +0100 Subject: [PATCH] fixes #206 (#207) --- .../me/vripper/download/DownloadService.kt | 36 ++++-------- .../vripper/download/ImageDownloadContext.kt | 14 +++++ .../vripper/download/ImageDownloadRunnable.kt | 6 +- .../main/kotlin/me/vripper/event/EventBus.kt | 7 ++- .../src/main/kotlin/me/vripper/host/Host.kt | 29 ++++++---- .../me/vripper/services/DataTransaction.kt | 58 +++++-------------- .../vripper/services/DownloadSpeedService.kt | 1 - .../me/vripper/services/SettingsService.kt | 13 +---- .../me/vripper/services/VGAuthService.kt | 22 ++----- .../src/main/kotlin/me/vripper/tasks/Tasks.kt | 13 +---- .../me/vripper/gui/VripperGuiApplication.kt | 4 +- .../fragments/ColumnSelectionFragment.kt | 19 ------ .../components/fragments/RenameFragment.kt | 5 ++ .../components/fragments/SettingsFragment.kt | 5 +- .../gui/components/views/ActionBarView.kt | 10 +++- .../gui/components/views/LoadingView.kt | 6 +- .../gui/components/views/LogTableView.kt | 4 +- .../gui/components/views/MenuBarView.kt | 19 ++++-- .../gui/components/views/PostsTableView.kt | 8 ++- .../gui/components/views/ThreadTableView.kt | 6 +- 20 files changed, 119 insertions(+), 166 deletions(-) delete mode 100644 vripper-gui/src/main/kotlin/me/vripper/gui/components/fragments/ColumnSelectionFragment.kt diff --git a/vripper-core/src/main/kotlin/me/vripper/download/DownloadService.kt b/vripper-core/src/main/kotlin/me/vripper/download/DownloadService.kt index 3415f47..780c55b 100644 --- a/vripper-core/src/main/kotlin/me/vripper/download/DownloadService.kt +++ b/vripper-core/src/main/kotlin/me/vripper/download/DownloadService.kt @@ -1,8 +1,6 @@ package me.vripper.download -import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Runnable -import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import me.vripper.entities.ImageEntity import me.vripper.entities.PostEntity @@ -39,7 +37,6 @@ internal class DownloadService( private val pending: MutableMap> = mutableMapOf() private val lock = ReentrantLock() private val condition = lock.newCondition() - private val coroutineScope = CoroutineScope(SupervisorJob()) init { Thread.ofVirtual().name("Download Loop").unstarted(Runnable { @@ -74,14 +71,10 @@ internal class DownloadService( fun stop(postIds: List = emptyList()) { if (postIds.isNotEmpty()) { stopInternal(postIds) - coroutineScope.launch { - eventBus.publishEvent(StoppedEvent(postIds)) - } + eventBus.publishEvent(StoppedEvent(postIds)) } else { stopAll() - coroutineScope.launch { - eventBus.publishEvent(StoppedEvent(listOf(-1))) - } + eventBus.publishEvent(StoppedEvent(listOf(-1))) } } @@ -89,8 +82,9 @@ internal class DownloadService( if (postEntityIds.isNotEmpty()) { restart(postEntityIds.associateWith { dataTransaction.findByPostIdAndIsNotCompleted(it.postId) }) } else { - restart(dataTransaction.findAllPosts() - .associateWith { dataTransaction.findByPostIdAndIsNotCompleted(it.postId) }) + restart( + dataTransaction.findAllPosts() + .associateWith { dataTransaction.findByPostIdAndIsNotCompleted(it.postId) }) } } @@ -237,9 +231,7 @@ internal class DownloadService( private fun scheduleForDownload(imageDownloadRunnable: ImageDownloadRunnable) { log.debug("Scheduling a job for ${imageDownloadRunnable.context.imageEntity.url}") GlobalScopeCoroutine.launch { - coroutineScope.launch { - eventBus.publishEvent(QueueStateEvent(QueueState(runningCount(), pendingCount()))) - } + eventBus.publishEvent(QueueStateEvent(QueueState(runningCount(), pendingCount()))) try { Failsafe.with>(retryPolicyService.buildRetryPolicyForDownload("Failed to download ${imageDownloadRunnable.context.imageEntity.url}: ")) .onFailure { @@ -253,18 +245,14 @@ internal class DownloadService( } .onComplete { afterJobFinish(imageDownloadRunnable) - coroutineScope.launch { - eventBus.publishEvent( - QueueStateEvent( - QueueState( - runningCount(), pendingCount() - ) + eventBus.publishEvent( + QueueStateEvent( + QueueState( + runningCount(), pendingCount() ) ) - } - coroutineScope.launch { - eventBus.publishEvent(ErrorCountEvent(ErrorCount(dataTransaction.countImagesInError()))) - } + ) + eventBus.publishEvent(ErrorCountEvent(ErrorCount(dataTransaction.countImagesInError()))) log.debug( "Finished downloading ${imageDownloadRunnable.context.imageEntity.url}" ) diff --git a/vripper-core/src/main/kotlin/me/vripper/download/ImageDownloadContext.kt b/vripper-core/src/main/kotlin/me/vripper/download/ImageDownloadContext.kt index 50d6157..7231f24 100644 --- a/vripper-core/src/main/kotlin/me/vripper/download/ImageDownloadContext.kt +++ b/vripper-core/src/main/kotlin/me/vripper/download/ImageDownloadContext.kt @@ -1,5 +1,6 @@ package me.vripper.download +import kotlinx.coroutines.* import me.vripper.entities.ImageEntity import me.vripper.model.Settings import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase @@ -8,10 +9,23 @@ import org.apache.hc.client5.http.protocol.HttpClientContext import org.koin.core.component.KoinComponent internal class ImageDownloadContext(val imageEntity: ImageEntity, val settings: Settings) : KoinComponent { + private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Default) + private val jobs = mutableListOf() val httpContext: HttpClientContext = HttpClientContext.create().apply { cookieStore = BasicCookieStore() } val requests = mutableListOf() val postId = imageEntity.postIdRef var stopped = false var completed = false + + fun cancelCoroutines() { + runBlocking { + coroutineScope.cancel() + jobs.forEach { job -> job.cancelAndJoin() } + } + } + + fun launchCoroutine(block: suspend CoroutineScope.() -> Unit): Job { + return coroutineScope.launch(block = block).also { job -> jobs.add(job) } + } } \ No newline at end of file diff --git a/vripper-core/src/main/kotlin/me/vripper/download/ImageDownloadRunnable.kt b/vripper-core/src/main/kotlin/me/vripper/download/ImageDownloadRunnable.kt index d5e9574..45a9f4a 100644 --- a/vripper-core/src/main/kotlin/me/vripper/download/ImageDownloadRunnable.kt +++ b/vripper-core/src/main/kotlin/me/vripper/download/ImageDownloadRunnable.kt @@ -8,7 +8,7 @@ import me.vripper.host.DownloadedImage import me.vripper.host.Host import me.vripper.host.ImageMimeType import me.vripper.model.Settings -import me.vripper.services.* +import me.vripper.services.DataTransaction import me.vripper.utilities.LoggerDelegate import me.vripper.utilities.PathUtils.getExtension import me.vripper.utilities.PathUtils.getFileNameWithoutExtension @@ -21,6 +21,7 @@ import java.nio.file.Files import java.nio.file.Path import java.nio.file.StandardCopyOption import java.util.* +import kotlin.Throws import kotlin.io.path.Path import kotlin.io.path.pathString @@ -127,6 +128,7 @@ internal class ImageDownloadRunnable( download() } finally { context.completed = true + context.cancelCoroutines() } } @@ -143,6 +145,8 @@ internal class ImageDownloadRunnable( fun stop() { context.requests.forEach { it.abort() } + context.cancelCoroutines() context.stopped = true + dataTransaction.updateImage(context.imageEntity) } } \ No newline at end of file diff --git a/vripper-core/src/main/kotlin/me/vripper/event/EventBus.kt b/vripper-core/src/main/kotlin/me/vripper/event/EventBus.kt index f9b1f6d..0c34841 100644 --- a/vripper-core/src/main/kotlin/me/vripper/event/EventBus.kt +++ b/vripper-core/src/main/kotlin/me/vripper/event/EventBus.kt @@ -1,14 +1,15 @@ package me.vripper.event +import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.asSharedFlow object EventBus { - private val _events = MutableSharedFlow() + private val _events = MutableSharedFlow(0, Int.MAX_VALUE, BufferOverflow.DROP_OLDEST) val events = _events.asSharedFlow() - suspend fun publishEvent(event: Any) { - _events.emit(event) + fun publishEvent(event: Any) { + _events.tryEmit(event) } } diff --git a/vripper-core/src/main/kotlin/me/vripper/host/Host.kt b/vripper-core/src/main/kotlin/me/vripper/host/Host.kt index 506a76c..e8642f1 100644 --- a/vripper-core/src/main/kotlin/me/vripper/host/Host.kt +++ b/vripper-core/src/main/kotlin/me/vripper/host/Host.kt @@ -1,5 +1,9 @@ package me.vripper.host +import kotlinx.coroutines.cancelAndJoin +import kotlinx.coroutines.delay +import kotlinx.coroutines.isActive +import kotlinx.coroutines.runBlocking import me.vripper.download.ImageDownloadContext import me.vripper.exception.DownloadException import me.vripper.exception.HostException @@ -15,10 +19,9 @@ import org.apache.hc.core5.http.ClassicHttpResponse import org.apache.hc.core5.http.Header import org.jetbrains.exposed.sql.transactions.transaction import org.w3c.dom.Document +import java.io.BufferedOutputStream import java.nio.file.Files import java.nio.file.Path -import java.time.Duration -import java.time.LocalDateTime import kotlin.Throws internal abstract class Host( @@ -100,7 +103,7 @@ internal abstract class Host( "vripper_", ".tmp" ) - return Files.newOutputStream(tempImage).use { fos -> + return BufferedOutputStream(Files.newOutputStream(tempImage)).use { bos -> val image = context.imageEntity synchronized(image.postId.toString().intern()) { val post = dataTransaction.findPostById(context.postId).orElseThrow() @@ -124,20 +127,22 @@ internal abstract class Host( ) val buffer = ByteArray(READ_BUFFER_SIZE) var read: Int - var lastImageUpdateDate = LocalDateTime.now() - while (response.entity.content.read(buffer, 0, READ_BUFFER_SIZE) + val reporterJob = context.launchCoroutine { + while (isActive) { + dataTransaction.updateImage(image, false) + delay(100) + } + } + while (response.entity.content.read(buffer) .also { read = it } != -1 && !context.stopped ) { - fos.write(buffer, 0, read) + bos.write(buffer, 0, read) image.downloaded += read - if (Duration.between(lastImageUpdateDate, LocalDateTime.now()).toMillis() > 1750) { - dataTransaction.updateImage(image) - lastImageUpdateDate = LocalDateTime.now() - } else { - dataTransaction.updateImage(image, false) - } downloadSpeedService.reportDownloadedBytes(read.toLong()) } + runBlocking { + reporterJob.cancelAndJoin() + } dataTransaction.updateImage(image) Pair(tempImage, mimeType) } diff --git a/vripper-core/src/main/kotlin/me/vripper/services/DataTransaction.kt b/vripper-core/src/main/kotlin/me/vripper/services/DataTransaction.kt index b5e08aa..d24b711 100644 --- a/vripper-core/src/main/kotlin/me/vripper/services/DataTransaction.kt +++ b/vripper-core/src/main/kotlin/me/vripper/services/DataTransaction.kt @@ -1,9 +1,5 @@ package me.vripper.services -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.launch import me.vripper.data.repositories.ImageRepository import me.vripper.data.repositories.MetadataRepository import me.vripper.data.repositories.PostDownloadStateRepository @@ -28,7 +24,6 @@ internal class DataTransaction( private val eventBus: EventBus, ) { - private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Default) private val nextRank = AtomicInteger(transaction { getQueuePosition() }?.plus(1) ?: 0) private fun save(postEntities: List): List { @@ -42,44 +37,32 @@ internal class DataTransaction( save(images.map { it.copy(postIdRef = savedPost.id) }) savedPost } - coroutineScope.launch { - eventBus.publishEvent(PostCreateEvent(listOf(savedPost))) - } + eventBus.publishEvent(PostCreateEvent(listOf(savedPost))) } fun updatePosts(postEntities: List) { transaction { postDownloadStateRepository.update(postEntities) } - coroutineScope.launch { - eventBus.publishEvent(PostUpdateEvent(postEntities)) - } + eventBus.publishEvent(PostUpdateEvent(postEntities)) } fun updatePost(postEntity: PostEntity) { transaction { postDownloadStateRepository.update(postEntity) } - coroutineScope.launch { - eventBus.publishEvent(PostUpdateEvent(listOf(postEntity))) - } + eventBus.publishEvent(PostUpdateEvent(listOf(postEntity))) } fun save(threadEntity: ThreadEntity) { val savedThread = transaction { threadRepository.save(threadEntity) } - coroutineScope.launch { - eventBus.publishEvent(ThreadCreateEvent(savedThread)) - } + eventBus.publishEvent(ThreadCreateEvent(savedThread)) } fun update(threadEntity: ThreadEntity) { transaction { threadRepository.update(threadEntity) } - coroutineScope.launch { - eventBus.publishEvent(ThreadUpdateEvent(threadEntity)) - } + eventBus.publishEvent(ThreadUpdateEvent(threadEntity)) } fun updateImages(imageEntities: List) { transaction { imageRepository.update(imageEntities) } - coroutineScope.launch { - eventBus.publishEvent(ImageEvent(imageEntities)) - } + eventBus.publishEvent(ImageEvent(imageEntities)) } fun updateImage(imageEntity: ImageEntity, persist: Boolean = true) { @@ -88,9 +71,7 @@ internal class DataTransaction( imageRepository.update(imageEntity) } } - coroutineScope.launch { - eventBus.publishEvent(ImageEvent(listOf(imageEntity))) - } + eventBus.publishEvent(ImageEvent(listOf(imageEntity))) } fun exists(postId: Long): Boolean { @@ -142,9 +123,7 @@ internal class DataTransaction( } savedPosts } - coroutineScope.launch { - eventBus.publishEvent(PostCreateEvent(savedPosts)) - } + eventBus.publishEvent(PostCreateEvent(savedPosts)) return savedPosts } @@ -191,20 +170,13 @@ internal class DataTransaction( postDownloadStateRepository.deleteAll(postIds) sortPostsByRank() } - - coroutineScope.launch { - eventBus.publishEvent(PostDeleteEvent(postIds = postIds)) - } - coroutineScope.launch { - eventBus.publishEvent(ErrorCountEvent(ErrorCount(countImagesInError()))) - } + eventBus.publishEvent(PostDeleteEvent(postIds = postIds)) + eventBus.publishEvent(ErrorCountEvent(ErrorCount(countImagesInError()))) } fun removeThread(threadId: Long) { transaction { threadRepository.deleteByThreadId(threadId) } - coroutineScope.launch { - eventBus.publishEvent(ThreadDeleteEvent(threadId)) - } + eventBus.publishEvent(ThreadDeleteEvent(threadId)) } fun clearCompleted(): List { @@ -231,16 +203,12 @@ internal class DataTransaction( fun saveMetadata(metadataEntity: MetadataEntity) { transaction { metadataRepository.save(metadataEntity) } - coroutineScope.launch { - eventBus.publishEvent(MetadataUpdateEvent(metadataEntity)) - } + eventBus.publishEvent(MetadataUpdateEvent(metadataEntity)) } fun clearQueueLinks() { transaction { threadRepository.deleteAll() } - coroutineScope.launch { - eventBus.publishEvent(ThreadClearEvent()) - } + eventBus.publishEvent(ThreadClearEvent()) } @Synchronized diff --git a/vripper-core/src/main/kotlin/me/vripper/services/DownloadSpeedService.kt b/vripper-core/src/main/kotlin/me/vripper/services/DownloadSpeedService.kt index 232733f..4e2cb49 100644 --- a/vripper-core/src/main/kotlin/me/vripper/services/DownloadSpeedService.kt +++ b/vripper-core/src/main/kotlin/me/vripper/services/DownloadSpeedService.kt @@ -30,7 +30,6 @@ internal class DownloadSpeedService( while (isActive) { delay(DOWNLOAD_POLL_RATE.toLong()) val newValue = bytesCount.getAndSet(0) - eventBus.publishEvent(DownloadSpeedEvent(DownloadSpeed(((newValue * 1000) / DOWNLOAD_POLL_RATE)))) } } diff --git a/vripper-core/src/main/kotlin/me/vripper/services/SettingsService.kt b/vripper-core/src/main/kotlin/me/vripper/services/SettingsService.kt index 9d46c7e..7f88ac6 100644 --- a/vripper-core/src/main/kotlin/me/vripper/services/SettingsService.kt +++ b/vripper-core/src/main/kotlin/me/vripper/services/SettingsService.kt @@ -1,9 +1,5 @@ package me.vripper.services -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.launch import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import kotlinx.serialization.json.decodeFromStream @@ -24,7 +20,6 @@ class SettingsService(private val eventBus: EventBus) { private val configPath = VRIPPER_DIR.resolve("config.json") private val customProxiesPath = VRIPPER_DIR.resolve("proxies.json") private val proxies: MutableSet = HashSet() - private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Default) private val json = Json { encodeDefaults = true @@ -40,9 +35,7 @@ class SettingsService(private val eventBus: EventBus) { private fun init() { loadViperProxies() restore() - coroutineScope.launch { - eventBus.publishEvent(SettingsUpdateEvent(settings)) - } + eventBus.publishEvent(SettingsUpdateEvent(settings)) } private fun loadViperProxies() { @@ -100,9 +93,7 @@ class SettingsService(private val eventBus: EventBus) { } this.settings = settings.copy(viperSettings = viperSettings) save() - coroutineScope.launch { - eventBus.publishEvent(SettingsUpdateEvent(this@SettingsService.settings)) - } + eventBus.publishEvent(SettingsUpdateEvent(this@SettingsService.settings)) } private fun restore() { diff --git a/vripper-core/src/main/kotlin/me/vripper/services/VGAuthService.kt b/vripper-core/src/main/kotlin/me/vripper/services/VGAuthService.kt index a2e7dc8..a0a5c83 100644 --- a/vripper-core/src/main/kotlin/me/vripper/services/VGAuthService.kt +++ b/vripper-core/src/main/kotlin/me/vripper/services/VGAuthService.kt @@ -50,10 +50,7 @@ internal class VGAuthService( log.debug("Authentication option is disabled") context.cookieStore.clear() loggedUser = "" - coroutineScope.launch { - eventBus.publishEvent(VGUserLoginEvent(loggedUser)) - } - + eventBus.publishEvent(VGUserLoginEvent(loggedUser)) return } val username = settings.viperSettings.username @@ -62,11 +59,7 @@ internal class VGAuthService( log.error("Cannot authenticate with ViperGirls credentials, username or password is empty") context.cookieStore.clear() loggedUser = "" - - coroutineScope.launch { - eventBus.publishEvent(VGUserLoginEvent(loggedUser)) - } - + eventBus.publishEvent(VGUserLoginEvent(loggedUser)) return } val postAuth = HttpPost(settings.viperSettings.host + "/login.php?do=login").also { @@ -103,11 +96,7 @@ internal class VGAuthService( } catch (e: Exception) { context.cookieStore.clear() loggedUser = "" - - coroutineScope.launch { - eventBus.publishEvent(VGUserLoginEvent(loggedUser)) - } - + eventBus.publishEvent(VGUserLoginEvent(loggedUser)) log.error( "Failed to authenticate user with " + settings.viperSettings.host, e ) @@ -115,10 +104,7 @@ internal class VGAuthService( } authenticated = true loggedUser = username - - coroutineScope.launch { - eventBus.publishEvent(VGUserLoginEvent(loggedUser)) - } + eventBus.publishEvent(VGUserLoginEvent(loggedUser)) } fun leaveThanks(postEntity: PostEntity) { diff --git a/vripper-core/src/main/kotlin/me/vripper/tasks/Tasks.kt b/vripper-core/src/main/kotlin/me/vripper/tasks/Tasks.kt index 0f9a0cc..691ca46 100644 --- a/vripper-core/src/main/kotlin/me/vripper/tasks/Tasks.kt +++ b/vripper-core/src/main/kotlin/me/vripper/tasks/Tasks.kt @@ -1,9 +1,5 @@ package me.vripper.tasks -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.launch import me.vripper.event.EventBus import me.vripper.event.LoadingTasks import org.koin.core.component.KoinComponent @@ -13,14 +9,11 @@ internal object Tasks : KoinComponent { private val eventBus: EventBus by inject() private var current = 0 - private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Default) @Synchronized fun increment() { if (current == 0) { - coroutineScope.launch { - eventBus.publishEvent(LoadingTasks(true)) - } + eventBus.publishEvent(LoadingTasks(true)) } current += 1 } @@ -29,9 +22,7 @@ internal object Tasks : KoinComponent { fun decrement() { current -= 1 if (current == 0) { - coroutineScope.launch { - eventBus.publishEvent(LoadingTasks(false)) - } + eventBus.publishEvent(LoadingTasks(false)) } } } diff --git a/vripper-gui/src/main/kotlin/me/vripper/gui/VripperGuiApplication.kt b/vripper-gui/src/main/kotlin/me/vripper/gui/VripperGuiApplication.kt index ff91008..37f9fc1 100644 --- a/vripper-gui/src/main/kotlin/me/vripper/gui/VripperGuiApplication.kt +++ b/vripper-gui/src/main/kotlin/me/vripper/gui/VripperGuiApplication.kt @@ -49,8 +49,8 @@ class VripperGuiApplication : App( with(stage) { width = widgetsController.currentSettings.width height = widgetsController.currentSettings.height - minWidth = 800.0 - minHeight = 600.0 + minWidth = 100.0 + minHeight = 100.0 icons.addAll( listOf( Image("icons/16x16.png"), diff --git a/vripper-gui/src/main/kotlin/me/vripper/gui/components/fragments/ColumnSelectionFragment.kt b/vripper-gui/src/main/kotlin/me/vripper/gui/components/fragments/ColumnSelectionFragment.kt deleted file mode 100644 index 460d914..0000000 --- a/vripper-gui/src/main/kotlin/me/vripper/gui/components/fragments/ColumnSelectionFragment.kt +++ /dev/null @@ -1,19 +0,0 @@ -package me.vripper.gui.components.fragments - -import javafx.beans.property.SimpleBooleanProperty -import javafx.collections.FXCollections -import tornadofx.Fragment -import tornadofx.listview -import tornadofx.useCheckbox - -class ColumnSelectionFragment : Fragment("Column Selection") { - - val map: MutableMap by param() - - override val root = listview { - items = FXCollections.observableArrayList(map.keys) - useCheckbox { listItem -> - map[listItem]!! - } - } -} \ No newline at end of file diff --git a/vripper-gui/src/main/kotlin/me/vripper/gui/components/fragments/RenameFragment.kt b/vripper-gui/src/main/kotlin/me/vripper/gui/components/fragments/RenameFragment.kt index bc0682a..88667bc 100644 --- a/vripper-gui/src/main/kotlin/me/vripper/gui/components/fragments/RenameFragment.kt +++ b/vripper-gui/src/main/kotlin/me/vripper/gui/components/fragments/RenameFragment.kt @@ -1,10 +1,13 @@ package me.vripper.gui.components.fragments +import atlantafx.base.theme.Styles import javafx.beans.property.SimpleStringProperty import javafx.geometry.Pos import javafx.scene.control.ComboBox import kotlinx.coroutines.* import me.vripper.gui.controller.PostController +import org.kordamp.ikonli.feather.Feather +import org.kordamp.ikonli.javafx.FontIcon import tornadofx.* class RenameFragment : Fragment("Rename download post") { @@ -35,6 +38,8 @@ class RenameFragment : Fragment("Rename download post") { } } button("Rename") { + graphic = FontIcon.of(Feather.EDIT) + addClass(Styles.ACCENT) disableWhen(comboBox.editor.textProperty().isEmpty) action { coroutineScope.launch { diff --git a/vripper-gui/src/main/kotlin/me/vripper/gui/components/fragments/SettingsFragment.kt b/vripper-gui/src/main/kotlin/me/vripper/gui/components/fragments/SettingsFragment.kt index d79f96e..658c293 100644 --- a/vripper-gui/src/main/kotlin/me/vripper/gui/components/fragments/SettingsFragment.kt +++ b/vripper-gui/src/main/kotlin/me/vripper/gui/components/fragments/SettingsFragment.kt @@ -31,8 +31,9 @@ class SettingsFragment : Fragment("Settings") { tabpane { tabClosingPolicy = TabPane.TabClosingPolicy.UNAVAILABLE VBox.setVgrow(this, Priority.ALWAYS) - minWidth = 700.0 - minHeight = 400.0 + minWidth = 100.0 + minHeight = 100.0 + prefHeight = 400.0 tab(downloadSettingsFragment.title) { add(downloadSettingsFragment) graphic = FontIcon.of(Feather.FOLDER) diff --git a/vripper-gui/src/main/kotlin/me/vripper/gui/components/views/ActionBarView.kt b/vripper-gui/src/main/kotlin/me/vripper/gui/components/views/ActionBarView.kt index 48f5c2a..e4ccbb7 100644 --- a/vripper-gui/src/main/kotlin/me/vripper/gui/components/views/ActionBarView.kt +++ b/vripper-gui/src/main/kotlin/me/vripper/gui/components/views/ActionBarView.kt @@ -60,7 +60,10 @@ class ActionBarView : View() { action { find().apply { input.clear() - }.openModal() + }.openModal()?.apply { + minWidth = 100.0 + minHeight = 100.0 + } } } separator(Orientation.VERTICAL) @@ -111,7 +114,10 @@ class ActionBarView : View() { contentDisplay = ContentDisplay.GRAPHIC_ONLY tooltip("Open settings menu [Ctrl+P]") action { - find().openModal(owner = primaryStage) + find().openModal()?.apply { + minWidth = 100.0 + minHeight = 100.0 + } } } separator(Orientation.VERTICAL) diff --git a/vripper-gui/src/main/kotlin/me/vripper/gui/components/views/LoadingView.kt b/vripper-gui/src/main/kotlin/me/vripper/gui/components/views/LoadingView.kt index fbb103e..abd1683 100644 --- a/vripper-gui/src/main/kotlin/me/vripper/gui/components/views/LoadingView.kt +++ b/vripper-gui/src/main/kotlin/me/vripper/gui/components/views/LoadingView.kt @@ -51,10 +51,12 @@ class LoadingView : View("VRipper") { if (!grpcEndpointService.ready()) { val sessionView = find() runLater { - sessionView.openModal().also { - it?.setOnCloseRequest { + sessionView.openModal()?.apply { + setOnCloseRequest { VripperGuiApplication.APP_INSTANCE.stop() } + minWidth = 100.0 + minHeight = 100.0 } } } diff --git a/vripper-gui/src/main/kotlin/me/vripper/gui/components/views/LogTableView.kt b/vripper-gui/src/main/kotlin/me/vripper/gui/components/views/LogTableView.kt index e5137b2..9676ebe 100644 --- a/vripper-gui/src/main/kotlin/me/vripper/gui/components/views/LogTableView.kt +++ b/vripper-gui/src/main/kotlin/me/vripper/gui/components/views/LogTableView.kt @@ -228,8 +228,8 @@ class LogTableView : View() { private fun openLog(item: LogModel) { find(mapOf(LogMessageFragment::logModel to item)).openModal()?.apply { - minWidth = 600.0 - minHeight = 400.0 + minWidth = 100.0 + minHeight = 100.0 } } } diff --git a/vripper-gui/src/main/kotlin/me/vripper/gui/components/views/MenuBarView.kt b/vripper-gui/src/main/kotlin/me/vripper/gui/components/views/MenuBarView.kt index aa85afa..2bb25c3 100644 --- a/vripper-gui/src/main/kotlin/me/vripper/gui/components/views/MenuBarView.kt +++ b/vripper-gui/src/main/kotlin/me/vripper/gui/components/views/MenuBarView.kt @@ -67,7 +67,10 @@ class MenuBarView : View() { action { find().apply { input.clear() - }.openModal() + }.openModal()?.apply { + minWidth = 100.0 + minHeight = 100.0 + } } } separator() @@ -113,14 +116,20 @@ class MenuBarView : View() { item("Settings", KeyCodeCombination(KeyCode.P, KeyCombination.CONTROL_DOWN)).apply { graphic = FontIcon.of(Feather.SETTINGS) action { - find().openModal(owner = primaryStage) + find().openModal()?.apply { + minWidth = 100.0 + minHeight = 100.0 + } } } separator() item("Change session", KeyCodeCombination(KeyCode.S, KeyCombination.SHIFT_DOWN)) { graphic = FontIcon.of(Feather.LINK_2) action { - find().openModal() + find().openModal()?.apply { + minWidth = 100.0 + minHeight = 100.0 + } } } separator() @@ -206,8 +215,8 @@ class MenuBarView : View() { graphic = FontIcon.of(Feather.INFO) action { find().openModal()?.apply { - this.minWidth = 625.0 - this.minHeight = 200.0 + this.minWidth = 100.0 + this.minHeight = 100.0 } } } diff --git a/vripper-gui/src/main/kotlin/me/vripper/gui/components/views/PostsTableView.kt b/vripper-gui/src/main/kotlin/me/vripper/gui/components/views/PostsTableView.kt index ed305ae..976ae6a 100644 --- a/vripper-gui/src/main/kotlin/me/vripper/gui/components/views/PostsTableView.kt +++ b/vripper-gui/src/main/kotlin/me/vripper/gui/components/views/PostsTableView.kt @@ -178,7 +178,10 @@ class PostsTableView : View() { action { find().apply { input.clear() - }.openModal() + }.openModal()?.apply { + minWidth = 100.0 + minHeight = 100.0 + } } }) column("Preview", PostModel::previewListProperty) { @@ -469,7 +472,8 @@ class PostsTableView : View() { RenameFragment::altTitles to post.altTitles ) ).openModal()?.apply { - minWidth = 450.0 + minWidth = 100.0 + minHeight = 100.0 } } diff --git a/vripper-gui/src/main/kotlin/me/vripper/gui/components/views/ThreadTableView.kt b/vripper-gui/src/main/kotlin/me/vripper/gui/components/views/ThreadTableView.kt index 7a42fef..72909e5 100644 --- a/vripper-gui/src/main/kotlin/me/vripper/gui/components/views/ThreadTableView.kt +++ b/vripper-gui/src/main/kotlin/me/vripper/gui/components/views/ThreadTableView.kt @@ -248,10 +248,8 @@ class ThreadTableView : View() { private fun selectPosts(threadId: Long) { find(mapOf(ThreadSelectionTableFragment::threadId to threadId)).openModal() ?.apply { - minWidth = 600.0 - minHeight = 400.0 - width = 800.0 - height = 600.0 + minWidth = 100.0 + minHeight = 100.0 } } } \ No newline at end of file