Skip to content

Commit c71a98e

Browse files
committed
feat: add custom title bar with window control functionality and update dependencies
1 parent 872e50f commit c71a98e

File tree

5 files changed

+332
-34
lines changed

5 files changed

+332
-34
lines changed

composeApp/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ kotlin {
159159
implementation(compose.desktop.currentOs)
160160
implementation(libs.kotlinx.coroutinesSwing)
161161
implementation(libs.sentry.jvm)
162+
implementation(libs.native.tray)
162163
implementation(projects.mediaJvmUi)
163164
}
164165
}

composeApp/src/commonMain/kotlin/com/maxrave/simpmusic/viewModel/SharedViewModel.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ import simpmusic.composeapp.generated.resources.shared
9898
import simpmusic.composeapp.generated.resources.updated
9999
import simpmusic.composeapp.generated.resources.vote_submitted
100100
import java.io.FileOutputStream
101-
import java.lang.Exception
102101
import kotlin.math.abs
103102
import kotlin.reflect.KClass
104103

@@ -1671,6 +1670,7 @@ class SharedViewModel(
16711670
_lyricsVoteState.update {
16721671
it?.copy(
16731672
state = VoteState.Success(upvote),
1673+
vote = it.vote + if (upvote) 1 else -1
16741674
)
16751675
}
16761676
makeToast(getString(Res.string.vote_submitted))
@@ -1722,7 +1722,12 @@ class SharedViewModel(
17221722

17231723
is Resource.Success -> {
17241724
Logger.d(tag, "Vote SimpMusic Translated Lyrics Success")
1725-
_translatedVoteState.update { it?.copy(state = VoteState.Success(upvote)) }
1725+
_translatedVoteState.update {
1726+
it?.copy(
1727+
state = VoteState.Success(upvote),
1728+
vote = it.vote + if (upvote) 1 else -1
1729+
)
1730+
}
17261731
makeToast(getString(Res.string.vote_submitted))
17271732
}
17281733
}

composeApp/src/jvmMain/kotlin/com/maxrave/simpmusic/main.kt

Lines changed: 82 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
package com.maxrave.simpmusic
22

3+
import androidx.compose.foundation.layout.Column
4+
import androidx.compose.foundation.layout.fillMaxSize
5+
import androidx.compose.foundation.shape.RoundedCornerShape
36
import androidx.compose.material3.ExperimentalMaterial3Api
7+
import androidx.compose.runtime.getValue
8+
import androidx.compose.runtime.mutableStateOf
9+
import androidx.compose.runtime.remember
10+
import androidx.compose.runtime.setValue
11+
import androidx.compose.ui.Modifier
12+
import androidx.compose.ui.draw.clip
413
import androidx.compose.ui.unit.DpSize
514
import androidx.compose.ui.unit.dp
615
import androidx.compose.ui.window.Window
@@ -13,11 +22,13 @@ import coil3.disk.DiskCache
1322
import coil3.network.okhttp.OkHttpNetworkFetcherFactory
1423
import coil3.request.CachePolicy
1524
import coil3.request.crossfade
25+
import com.kdroid.composetray.tray.api.Tray
1626
import com.maxrave.data.di.loader.loadAllModules
1727
import com.maxrave.domain.manager.DataStoreManager
1828
import com.maxrave.domain.mediaservice.handler.MediaPlayerHandler
1929
import com.maxrave.domain.mediaservice.handler.ToastType
2030
import com.maxrave.simpmusic.di.viewModelModule
31+
import com.maxrave.simpmusic.ui.component.CustomTitleBar
2132
import com.maxrave.simpmusic.ui.mini_player.MiniPlayerManager
2233
import com.maxrave.simpmusic.ui.mini_player.MiniPlayerWindow
2334
import com.maxrave.simpmusic.utils.VersionManager
@@ -40,6 +51,7 @@ import org.koin.mp.KoinPlatform.getKoin
4051
import simpmusic.composeapp.generated.resources.Res
4152
import simpmusic.composeapp.generated.resources.circle_app_icon
4253
import simpmusic.composeapp.generated.resources.explicit_content_blocked
54+
import simpmusic.composeapp.generated.resources.mono
4355
import simpmusic.composeapp.generated.resources.time_out_check_internet_connection_or_change_piped_instance_in_settings
4456

4557
@OptIn(ExperimentalMaterial3Api::class)
@@ -103,41 +115,84 @@ fun main() {
103115
rememberWindowState(
104116
size = DpSize(1280.dp, 720.dp),
105117
)
106-
Window(
107-
onCloseRequest = {
118+
var isVisible by remember { mutableStateOf(true) }
119+
Tray(
120+
icon = painterResource(Res.drawable.mono),
121+
tooltip = "SimpMusic",
122+
primaryAction = {
123+
isVisible = true
124+
windowState.isMinimized = false
125+
}
126+
) {
127+
if (!isVisible) {
128+
Item("Open SimpMusic") {
129+
isVisible = true
130+
windowState.isMinimized = false
131+
}
132+
}
133+
if (MiniPlayerManager.isOpen) {
134+
Item("Close Miniplayer") {
135+
MiniPlayerManager.isOpen = false
136+
}
137+
} else {
138+
Item("Open Miniplayer") {
139+
MiniPlayerManager.isOpen = true
140+
}
141+
}
142+
Divider()
143+
Item("Quit app") {
108144
mediaPlayerHandler.release()
109145
exitApplication()
146+
}
147+
}
148+
Window(
149+
onCloseRequest = {
150+
isVisible = false
110151
},
111152
title = "SimpMusic",
112153
icon = painterResource(Res.drawable.circle_app_icon),
113-
undecorated = false,
154+
undecorated = true,
155+
transparent = true,
114156
state = windowState,
157+
visible = isVisible,
115158
) {
116-
val context = LocalPlatformContext.current
117-
setSingletonImageLoaderFactory {
118-
ImageLoader
119-
.Builder(context)
120-
.components {
121-
add(
122-
OkHttpNetworkFetcherFactory(
123-
callFactory = {
124-
OkHttpClient()
125-
},
126-
),
127-
)
128-
}.diskCachePolicy(CachePolicy.ENABLED)
129-
.networkCachePolicy(CachePolicy.ENABLED)
130-
.diskCache(
131-
DiskCache
132-
.Builder()
133-
.directory(FileSystem.SYSTEM_TEMPORARY_DIRECTORY / "image_cache")
134-
.maxSizeBytes(512L * 1024 * 1024)
135-
.build(),
136-
).crossfade(true)
137-
.build()
159+
Column(modifier = Modifier.fillMaxSize()
160+
.clip(RoundedCornerShape(12.dp))) {
161+
CustomTitleBar(
162+
title = "SimpMusic",
163+
windowState = windowState,
164+
window = window,
165+
onCloseRequest = {
166+
isVisible = false
167+
},
168+
)
169+
170+
val context = LocalPlatformContext.current
171+
setSingletonImageLoaderFactory {
172+
ImageLoader
173+
.Builder(context)
174+
.components {
175+
add(
176+
OkHttpNetworkFetcherFactory(
177+
callFactory = {
178+
OkHttpClient()
179+
},
180+
),
181+
)
182+
}.diskCachePolicy(CachePolicy.ENABLED)
183+
.networkCachePolicy(CachePolicy.ENABLED)
184+
.diskCache(
185+
DiskCache
186+
.Builder()
187+
.directory(FileSystem.SYSTEM_TEMPORARY_DIRECTORY / "image_cache")
188+
.maxSizeBytes(512L * 1024 * 1024)
189+
.build(),
190+
).crossfade(true)
191+
.build()
192+
}
193+
App()
194+
ToastHost()
138195
}
139-
App()
140-
ToastHost()
141196
}
142197

143198
// Mini Player Window (separate window)

0 commit comments

Comments
 (0)