Rename package to cy.hexor.furumi, add F-Droid compatibility

- Rename applicationId and all sources from com.example.furumi_android to cy.hexor.furumi
- Add WTFPL LICENSE
- Add fastlane metadata
- Add fdroiddata build metadata cy.hexor.furumi.yml
- Remove foojay-resolver plugin (blocked by F-Droid scanner)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Ultradesu
2026-06-09 10:41:23 +01:00
parent 9d49bd85cd
commit be59bcb380
68 changed files with 515 additions and 448 deletions
+13
View File
@@ -0,0 +1,13 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
+2 -2
View File
@@ -6,11 +6,11 @@ plugins {
}
android {
namespace = "com.example.furumi_android"
namespace = "cy.hexor.furumi"
compileSdk = 35
defaultConfig {
applicationId = "com.example.furumi_android"
applicationId = "cy.hexor.furumi"
minSdk = 24
targetSdk = 35
versionCode = 1
@@ -1,4 +1,4 @@
package com.example.furumi_android
package cy.hexor.furumi
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -19,6 +19,6 @@ class ExampleInstrumentedTest {
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.example.furumi_android", appContext.packageName)
assertEquals("cy.hexor.furumi", appContext.packageName)
}
}
@@ -1,4 +1,4 @@
package com.example.furumi_android
package cy.hexor.furumi
import android.app.Application
import dagger.hilt.android.HiltAndroidApp
@@ -1,4 +1,4 @@
package com.example.furumi_android
package cy.hexor.furumi
import android.Manifest
import android.content.Intent
@@ -19,10 +19,10 @@ import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.example.furumi_android.ui.login.LoginScreen
import com.example.furumi_android.ui.login.LoginViewModel
import com.example.furumi_android.ui.player.PlayerScreen
import com.example.furumi_android.ui.theme.FurumiTheme
import cy.hexor.furumi.ui.login.LoginScreen
import cy.hexor.furumi.ui.login.LoginViewModel
import cy.hexor.furumi.ui.player.PlayerScreen
import cy.hexor.furumi.ui.theme.FurumiTheme
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
@@ -1,11 +1,11 @@
package com.example.furumi_android.data.local
package cy.hexor.furumi.data.local
import android.content.Context
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey
import com.example.furumi_android.domain.model.AuthSession
import com.example.furumi_android.domain.model.AuthTokens
import com.example.furumi_android.domain.model.User
import cy.hexor.furumi.domain.model.AuthSession
import cy.hexor.furumi.domain.model.AuthTokens
import cy.hexor.furumi.domain.model.User
import com.squareup.moshi.Moshi
class AuthSessionStorage(context: Context, moshi: Moshi) {
@@ -1,4 +1,4 @@
package com.example.furumi_android.data.local
package cy.hexor.furumi.data.local
import android.content.Context
import dagger.hilt.android.qualifiers.ApplicationContext
@@ -1,6 +1,6 @@
package com.example.furumi_android.data.remote
package cy.hexor.furumi.data.remote
import com.example.furumi_android.data.local.AuthSessionStorage
import cy.hexor.furumi.data.local.AuthSessionStorage
import okhttp3.Interceptor
import okhttp3.Response
import javax.inject.Inject
@@ -1,6 +1,6 @@
package com.example.furumi_android.data.remote
package cy.hexor.furumi.data.remote
import com.example.furumi_android.BuildConfig
import cy.hexor.furumi.BuildConfig
import javax.inject.Inject
import javax.inject.Singleton
@@ -1,6 +1,6 @@
package com.example.furumi_android.data.remote
package cy.hexor.furumi.data.remote
import com.example.furumi_android.data.remote.model.ErrorResponse
import cy.hexor.furumi.data.remote.model.ErrorResponse
import com.squareup.moshi.Moshi
import retrofit2.Response
import javax.inject.Inject
@@ -1,10 +1,10 @@
package com.example.furumi_android.data.remote
package cy.hexor.furumi.data.remote
import com.example.furumi_android.data.local.AuthSessionStorage
import com.example.furumi_android.data.remote.AccessTokenInterceptor.Companion.HEADER_AUTHORIZATION
import com.example.furumi_android.data.remote.api.AuthApi
import com.example.furumi_android.data.remote.model.RefreshRequest
import com.example.furumi_android.data.remote.model.toDomain
import cy.hexor.furumi.data.local.AuthSessionStorage
import cy.hexor.furumi.data.remote.AccessTokenInterceptor.Companion.HEADER_AUTHORIZATION
import cy.hexor.furumi.data.remote.api.AuthApi
import cy.hexor.furumi.data.remote.model.RefreshRequest
import cy.hexor.furumi.data.remote.model.toDomain
import dagger.Lazy
import kotlinx.coroutines.runBlocking
import okhttp3.Authenticator
@@ -54,7 +54,7 @@ class AuthAuthenticator @Inject constructor(
private suspend fun refreshTokens(
baseUrl: String,
refreshToken: String
): com.example.furumi_android.domain.model.AuthTokens? {
): cy.hexor.furumi.domain.model.AuthTokens? {
val refreshResponse = runCatching {
authApiLazy.get().refresh(
url = authEndpoints.refresh(baseUrl),
@@ -1,7 +1,7 @@
package com.example.furumi_android.data.remote
package cy.hexor.furumi.data.remote
import android.net.Uri
import com.example.furumi_android.domain.model.AuthException
import cy.hexor.furumi.domain.model.AuthException
import javax.inject.Inject
class AuthEndpoints @Inject constructor() {
@@ -1,4 +1,4 @@
package com.example.furumi_android.data.remote
package cy.hexor.furumi.data.remote
import javax.inject.Inject
@@ -1,12 +1,12 @@
package com.example.furumi_android.data.remote.api
package cy.hexor.furumi.data.remote.api
import com.example.furumi_android.data.remote.model.LoginRequest
import com.example.furumi_android.data.remote.model.LoginResponse
import com.example.furumi_android.data.remote.model.LogoutRequest
import com.example.furumi_android.data.remote.model.LogoutResponse
import com.example.furumi_android.data.remote.model.RefreshRequest
import com.example.furumi_android.data.remote.model.SsoExchangeRequest
import com.example.furumi_android.data.remote.model.TokenResponse
import cy.hexor.furumi.data.remote.model.LoginRequest
import cy.hexor.furumi.data.remote.model.LoginResponse
import cy.hexor.furumi.data.remote.model.LogoutRequest
import cy.hexor.furumi.data.remote.model.LogoutResponse
import cy.hexor.furumi.data.remote.model.RefreshRequest
import cy.hexor.furumi.data.remote.model.SsoExchangeRequest
import cy.hexor.furumi.data.remote.model.TokenResponse
import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.Header
@@ -1,26 +1,26 @@
package com.example.furumi_android.data.remote.api
package cy.hexor.furumi.data.remote.api
import com.example.furumi_android.data.remote.model.ArtistPageResponse
import com.example.furumi_android.data.remote.model.ArtistDetailResponse
import com.example.furumi_android.data.remote.model.PlayHistoryPageResponse
import com.example.furumi_android.data.remote.model.ReleaseDetailResponse
import com.example.furumi_android.data.remote.model.AddPlaylistTracksRequest
import com.example.furumi_android.data.remote.model.DeviceActiveRequest
import com.example.furumi_android.data.remote.model.DeviceCommandRequest
import com.example.furumi_android.data.remote.model.DevicePollRequest
import com.example.furumi_android.data.remote.model.DevicePollResponse
import com.example.furumi_android.data.remote.model.JamCreateRequest
import com.example.furumi_android.data.remote.model.JamInviteRequest
import com.example.furumi_android.data.remote.model.JamJoinRequest
import com.example.furumi_android.data.remote.model.JamUserResponse
import com.example.furumi_android.data.remote.model.LikeToggleResponse
import com.example.furumi_android.data.remote.model.LikedTrackIdsResponse
import com.example.furumi_android.data.remote.model.PlaylistCardResponse
import com.example.furumi_android.data.remote.model.PlaylistDetailResponse
import com.example.furumi_android.data.remote.model.RecordHistoryRequest
import com.example.furumi_android.data.remote.model.SearchResponse
import com.example.furumi_android.data.remote.model.SharePlaylistRequest
import com.example.furumi_android.data.remote.model.SharePlaylistResponse
import cy.hexor.furumi.data.remote.model.ArtistPageResponse
import cy.hexor.furumi.data.remote.model.ArtistDetailResponse
import cy.hexor.furumi.data.remote.model.PlayHistoryPageResponse
import cy.hexor.furumi.data.remote.model.ReleaseDetailResponse
import cy.hexor.furumi.data.remote.model.AddPlaylistTracksRequest
import cy.hexor.furumi.data.remote.model.DeviceActiveRequest
import cy.hexor.furumi.data.remote.model.DeviceCommandRequest
import cy.hexor.furumi.data.remote.model.DevicePollRequest
import cy.hexor.furumi.data.remote.model.DevicePollResponse
import cy.hexor.furumi.data.remote.model.JamCreateRequest
import cy.hexor.furumi.data.remote.model.JamInviteRequest
import cy.hexor.furumi.data.remote.model.JamJoinRequest
import cy.hexor.furumi.data.remote.model.JamUserResponse
import cy.hexor.furumi.data.remote.model.LikeToggleResponse
import cy.hexor.furumi.data.remote.model.LikedTrackIdsResponse
import cy.hexor.furumi.data.remote.model.PlaylistCardResponse
import cy.hexor.furumi.data.remote.model.PlaylistDetailResponse
import cy.hexor.furumi.data.remote.model.RecordHistoryRequest
import cy.hexor.furumi.data.remote.model.SearchResponse
import cy.hexor.furumi.data.remote.model.SharePlaylistRequest
import cy.hexor.furumi.data.remote.model.SharePlaylistResponse
import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.GET
@@ -1,8 +1,8 @@
package com.example.furumi_android.data.remote.model
package cy.hexor.furumi.data.remote.model
import com.example.furumi_android.domain.model.AuthSession
import com.example.furumi_android.domain.model.AuthTokens
import com.example.furumi_android.domain.model.User
import cy.hexor.furumi.domain.model.AuthSession
import cy.hexor.furumi.domain.model.AuthTokens
import cy.hexor.furumi.domain.model.User
fun LoginResponse.toDomainSession(
serverBaseUrl: String,
@@ -1,4 +1,4 @@
package com.example.furumi_android.data.remote.model
package cy.hexor.furumi.data.remote.model
import com.squareup.moshi.Json
@@ -1,4 +1,4 @@
package com.example.furumi_android.data.remote.model
package cy.hexor.furumi.data.remote.model
import com.squareup.moshi.Json
@@ -1,14 +1,14 @@
package com.example.furumi_android.data.remote.model
package cy.hexor.furumi.data.remote.model
import com.example.furumi_android.domain.model.ConnectedCommand
import com.example.furumi_android.domain.model.ConnectedCommandPayload
import com.example.furumi_android.domain.model.ConnectedDevice
import com.example.furumi_android.domain.model.ConnectedDevicesState
import com.example.furumi_android.domain.model.ConnectedJam
import com.example.furumi_android.domain.model.ConnectedJamMember
import com.example.furumi_android.domain.model.ConnectedJamUser
import com.example.furumi_android.domain.model.ConnectedPlaybackState
import com.example.furumi_android.domain.model.TrackCard
import cy.hexor.furumi.domain.model.ConnectedCommand
import cy.hexor.furumi.domain.model.ConnectedCommandPayload
import cy.hexor.furumi.domain.model.ConnectedDevice
import cy.hexor.furumi.domain.model.ConnectedDevicesState
import cy.hexor.furumi.domain.model.ConnectedJam
import cy.hexor.furumi.domain.model.ConnectedJamMember
import cy.hexor.furumi.domain.model.ConnectedJamUser
import cy.hexor.furumi.domain.model.ConnectedPlaybackState
import cy.hexor.furumi.domain.model.TrackCard
import com.squareup.moshi.Json
data class ConnectedPlaybackStateBody(
@@ -1,17 +1,17 @@
package com.example.furumi_android.data.remote.model
package cy.hexor.furumi.data.remote.model
import com.example.furumi_android.domain.model.ArtistCard
import com.example.furumi_android.domain.model.ArtistDetail
import com.example.furumi_android.domain.model.ArtistPage
import com.example.furumi_android.domain.model.ArtistRef
import com.example.furumi_android.domain.model.ListeningHistoryItem
import com.example.furumi_android.domain.model.ListeningHistoryPage
import com.example.furumi_android.domain.model.PlaylistCard
import com.example.furumi_android.domain.model.PlaylistDetail
import com.example.furumi_android.domain.model.ReleaseCard
import com.example.furumi_android.domain.model.ReleaseDetail
import com.example.furumi_android.domain.model.SearchResults
import com.example.furumi_android.domain.model.TrackCard
import cy.hexor.furumi.domain.model.ArtistCard
import cy.hexor.furumi.domain.model.ArtistDetail
import cy.hexor.furumi.domain.model.ArtistPage
import cy.hexor.furumi.domain.model.ArtistRef
import cy.hexor.furumi.domain.model.ListeningHistoryItem
import cy.hexor.furumi.domain.model.ListeningHistoryPage
import cy.hexor.furumi.domain.model.PlaylistCard
import cy.hexor.furumi.domain.model.PlaylistDetail
import cy.hexor.furumi.domain.model.ReleaseCard
import cy.hexor.furumi.domain.model.ReleaseDetail
import cy.hexor.furumi.domain.model.SearchResults
import cy.hexor.furumi.domain.model.TrackCard
import com.squareup.moshi.Json
data class ArtistRefResponse(
@@ -1,4 +1,4 @@
package com.example.furumi_android.data.repository
package cy.hexor.furumi.data.repository
import android.os.Build
import javax.inject.Inject
@@ -1,18 +1,18 @@
package com.example.furumi_android.data.repository
package cy.hexor.furumi.data.repository
import com.example.furumi_android.data.local.AuthSessionStorage
import com.example.furumi_android.data.remote.AuthApiErrorParser
import com.example.furumi_android.data.remote.AuthEndpoints
import com.example.furumi_android.data.remote.api.AuthApi
import com.example.furumi_android.data.remote.model.LoginRequest
import com.example.furumi_android.data.remote.model.LoginResponse
import com.example.furumi_android.data.remote.model.LogoutRequest
import com.example.furumi_android.data.remote.model.SsoExchangeRequest
import com.example.furumi_android.data.remote.model.toDomainSession
import com.example.furumi_android.domain.model.AuthException
import com.example.furumi_android.domain.model.AuthSession
import com.example.furumi_android.domain.model.ServerConfig
import com.example.furumi_android.domain.repository.AuthRepository
import cy.hexor.furumi.data.local.AuthSessionStorage
import cy.hexor.furumi.data.remote.AuthApiErrorParser
import cy.hexor.furumi.data.remote.AuthEndpoints
import cy.hexor.furumi.data.remote.api.AuthApi
import cy.hexor.furumi.data.remote.model.LoginRequest
import cy.hexor.furumi.data.remote.model.LoginResponse
import cy.hexor.furumi.data.remote.model.LogoutRequest
import cy.hexor.furumi.data.remote.model.SsoExchangeRequest
import cy.hexor.furumi.data.remote.model.toDomainSession
import cy.hexor.furumi.domain.model.AuthException
import cy.hexor.furumi.domain.model.AuthSession
import cy.hexor.furumi.domain.model.ServerConfig
import cy.hexor.furumi.domain.repository.AuthRepository
import kotlinx.coroutines.CancellationException
import retrofit2.Response
import javax.inject.Inject
@@ -1,4 +1,4 @@
package com.example.furumi_android.data.repository
package cy.hexor.furumi.data.repository
import android.graphics.Bitmap
import android.graphics.BitmapFactory
@@ -1,38 +1,38 @@
package com.example.furumi_android.data.repository
package cy.hexor.furumi.data.repository
import com.example.furumi_android.data.local.AuthSessionStorage
import com.example.furumi_android.data.local.ConnectedDeviceStorage
import com.example.furumi_android.data.remote.AppClientInfo
import com.example.furumi_android.data.remote.AuthApiErrorParser
import com.example.furumi_android.data.remote.PlayerEndpoints
import com.example.furumi_android.data.remote.api.PlayerApi
import com.example.furumi_android.data.remote.model.AddPlaylistTracksRequest
import com.example.furumi_android.data.remote.model.ConnectedCommandPayloadBody
import com.example.furumi_android.data.remote.model.DeviceActiveRequest
import com.example.furumi_android.data.remote.model.DeviceCommandRequest
import com.example.furumi_android.data.remote.model.DevicePollRequest
import com.example.furumi_android.data.remote.model.JamCreateRequest
import com.example.furumi_android.data.remote.model.JamInviteRequest
import com.example.furumi_android.data.remote.model.JamJoinRequest
import com.example.furumi_android.data.remote.model.RecordHistoryRequest
import com.example.furumi_android.data.remote.model.toDomain
import com.example.furumi_android.data.remote.model.toBody
import com.example.furumi_android.data.remote.model.toCommandPayloadBody
import com.example.furumi_android.data.remote.model.toTrackItemResponse
import com.example.furumi_android.domain.model.ArtistDetail
import com.example.furumi_android.domain.model.ArtistPage
import com.example.furumi_android.domain.model.AuthException
import com.example.furumi_android.domain.model.ConnectedCommand
import com.example.furumi_android.domain.model.ConnectedDevicesState
import com.example.furumi_android.domain.model.ConnectedJamUser
import com.example.furumi_android.domain.model.ConnectedPlaybackState
import com.example.furumi_android.domain.model.ListeningHistoryPage
import com.example.furumi_android.domain.model.PlaylistCard
import com.example.furumi_android.domain.model.PlaylistDetail
import com.example.furumi_android.domain.model.ReleaseDetail
import com.example.furumi_android.domain.model.SearchResults
import com.example.furumi_android.domain.model.TrackCard
import com.example.furumi_android.domain.repository.PlayerRepository
import cy.hexor.furumi.data.local.AuthSessionStorage
import cy.hexor.furumi.data.local.ConnectedDeviceStorage
import cy.hexor.furumi.data.remote.AppClientInfo
import cy.hexor.furumi.data.remote.AuthApiErrorParser
import cy.hexor.furumi.data.remote.PlayerEndpoints
import cy.hexor.furumi.data.remote.api.PlayerApi
import cy.hexor.furumi.data.remote.model.AddPlaylistTracksRequest
import cy.hexor.furumi.data.remote.model.ConnectedCommandPayloadBody
import cy.hexor.furumi.data.remote.model.DeviceActiveRequest
import cy.hexor.furumi.data.remote.model.DeviceCommandRequest
import cy.hexor.furumi.data.remote.model.DevicePollRequest
import cy.hexor.furumi.data.remote.model.JamCreateRequest
import cy.hexor.furumi.data.remote.model.JamInviteRequest
import cy.hexor.furumi.data.remote.model.JamJoinRequest
import cy.hexor.furumi.data.remote.model.RecordHistoryRequest
import cy.hexor.furumi.data.remote.model.toDomain
import cy.hexor.furumi.data.remote.model.toBody
import cy.hexor.furumi.data.remote.model.toCommandPayloadBody
import cy.hexor.furumi.data.remote.model.toTrackItemResponse
import cy.hexor.furumi.domain.model.ArtistDetail
import cy.hexor.furumi.domain.model.ArtistPage
import cy.hexor.furumi.domain.model.AuthException
import cy.hexor.furumi.domain.model.ConnectedCommand
import cy.hexor.furumi.domain.model.ConnectedDevicesState
import cy.hexor.furumi.domain.model.ConnectedJamUser
import cy.hexor.furumi.domain.model.ConnectedPlaybackState
import cy.hexor.furumi.domain.model.ListeningHistoryPage
import cy.hexor.furumi.domain.model.PlaylistCard
import cy.hexor.furumi.domain.model.PlaylistDetail
import cy.hexor.furumi.domain.model.ReleaseDetail
import cy.hexor.furumi.domain.model.SearchResults
import cy.hexor.furumi.domain.model.TrackCard
import cy.hexor.furumi.domain.repository.PlayerRepository
import kotlinx.coroutines.CancellationException
import javax.inject.Inject
@@ -1,12 +1,12 @@
package com.example.furumi_android.di
package cy.hexor.furumi.di
import com.example.furumi_android.data.local.AuthSessionStorage
import com.example.furumi_android.data.remote.AccessTokenInterceptor
import com.example.furumi_android.data.remote.AppClientInfo
import com.example.furumi_android.data.remote.AuthAuthenticator
import com.example.furumi_android.data.remote.AuthEndpoints
import com.example.furumi_android.data.remote.api.AuthApi
import com.example.furumi_android.data.remote.api.PlayerApi
import cy.hexor.furumi.data.local.AuthSessionStorage
import cy.hexor.furumi.data.remote.AccessTokenInterceptor
import cy.hexor.furumi.data.remote.AppClientInfo
import cy.hexor.furumi.data.remote.AuthAuthenticator
import cy.hexor.furumi.data.remote.AuthEndpoints
import cy.hexor.furumi.data.remote.api.AuthApi
import cy.hexor.furumi.data.remote.api.PlayerApi
import com.squareup.moshi.Moshi
import dagger.Lazy
import dagger.Module
@@ -1,9 +1,9 @@
package com.example.furumi_android.di
package cy.hexor.furumi.di
import com.example.furumi_android.data.repository.AuthRepositoryImpl
import com.example.furumi_android.data.repository.PlayerRepositoryImpl
import com.example.furumi_android.domain.repository.AuthRepository
import com.example.furumi_android.domain.repository.PlayerRepository
import cy.hexor.furumi.data.repository.AuthRepositoryImpl
import cy.hexor.furumi.data.repository.PlayerRepositoryImpl
import cy.hexor.furumi.domain.repository.AuthRepository
import cy.hexor.furumi.domain.repository.PlayerRepository
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
@@ -1,7 +1,7 @@
package com.example.furumi_android.di
package cy.hexor.furumi.di
import android.content.Context
import com.example.furumi_android.data.local.AuthSessionStorage
import cy.hexor.furumi.data.local.AuthSessionStorage
import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import dagger.Module
@@ -1,4 +1,4 @@
package com.example.furumi_android.domain.model
package cy.hexor.furumi.domain.model
data class ArtistCard(
val id: Long,
@@ -1,4 +1,4 @@
package com.example.furumi_android.domain.model
package cy.hexor.furumi.domain.model
class AuthException(
message: String,
@@ -1,4 +1,4 @@
package com.example.furumi_android.domain.model
package cy.hexor.furumi.domain.model
data class AuthSession(
val serverBaseUrl: String,
@@ -1,4 +1,4 @@
package com.example.furumi_android.domain.model
package cy.hexor.furumi.domain.model
data class AuthTokens(
val accessToken: String,
@@ -1,4 +1,4 @@
package com.example.furumi_android.domain.model
package cy.hexor.furumi.domain.model
data class ConnectedDevice(
val id: String,
@@ -1,4 +1,4 @@
package com.example.furumi_android.domain.model
package cy.hexor.furumi.domain.model
data class ListeningHistoryPage(
val items: List<ListeningHistoryItem>,
@@ -1,4 +1,4 @@
package com.example.furumi_android.domain.model
package cy.hexor.furumi.domain.model
import java.net.URI
import java.util.Locale
@@ -1,4 +1,4 @@
package com.example.furumi_android.domain.model
package cy.hexor.furumi.domain.model
data class User(
val id: Int,
@@ -1,8 +1,8 @@
package com.example.furumi_android.domain.repository
package cy.hexor.furumi.domain.repository
import com.example.furumi_android.domain.model.AuthSession
import com.example.furumi_android.domain.model.ServerConfig
import com.example.furumi_android.domain.model.User
import cy.hexor.furumi.domain.model.AuthSession
import cy.hexor.furumi.domain.model.ServerConfig
import cy.hexor.furumi.domain.model.User
interface AuthRepository {
suspend fun login(config: ServerConfig, password: String): Result<AuthSession>
@@ -1,17 +1,17 @@
package com.example.furumi_android.domain.repository
package cy.hexor.furumi.domain.repository
import com.example.furumi_android.domain.model.ArtistPage
import com.example.furumi_android.domain.model.ArtistDetail
import com.example.furumi_android.domain.model.ConnectedCommand
import com.example.furumi_android.domain.model.ConnectedDevicesState
import com.example.furumi_android.domain.model.ConnectedJamUser
import com.example.furumi_android.domain.model.ConnectedPlaybackState
import com.example.furumi_android.domain.model.ListeningHistoryPage
import com.example.furumi_android.domain.model.PlaylistCard
import com.example.furumi_android.domain.model.PlaylistDetail
import com.example.furumi_android.domain.model.ReleaseDetail
import com.example.furumi_android.domain.model.SearchResults
import com.example.furumi_android.domain.model.TrackCard
import cy.hexor.furumi.domain.model.ArtistPage
import cy.hexor.furumi.domain.model.ArtistDetail
import cy.hexor.furumi.domain.model.ConnectedCommand
import cy.hexor.furumi.domain.model.ConnectedDevicesState
import cy.hexor.furumi.domain.model.ConnectedJamUser
import cy.hexor.furumi.domain.model.ConnectedPlaybackState
import cy.hexor.furumi.domain.model.ListeningHistoryPage
import cy.hexor.furumi.domain.model.PlaylistCard
import cy.hexor.furumi.domain.model.PlaylistDetail
import cy.hexor.furumi.domain.model.ReleaseDetail
import cy.hexor.furumi.domain.model.SearchResults
import cy.hexor.furumi.domain.model.TrackCard
interface PlayerRepository {
suspend fun getArtists(
@@ -1,4 +1,4 @@
package com.example.furumi_android.playback
package cy.hexor.furumi.playback
import android.app.NotificationChannel
import android.app.NotificationManager
@@ -18,7 +18,7 @@ import androidx.media3.session.DefaultMediaNotificationProvider
import androidx.media3.session.MediaSession
import androidx.media3.session.MediaSessionService
import androidx.media3.session.MediaStyleNotificationHelper
import com.example.furumi_android.MainActivity
import cy.hexor.furumi.MainActivity
import com.google.common.util.concurrent.MoreExecutors
import dagger.hilt.android.AndroidEntryPoint
import okhttp3.OkHttpClient
@@ -1,4 +1,4 @@
package com.example.furumi_android.playback
package cy.hexor.furumi.playback
import android.content.Context
import android.content.Intent
@@ -16,8 +16,8 @@ import androidx.media3.common.util.UnstableApi
import androidx.media3.datasource.okhttp.OkHttpDataSource
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory
import com.example.furumi_android.domain.model.TrackCard
import com.example.furumi_android.domain.model.ConnectedPlaybackState
import cy.hexor.furumi.domain.model.TrackCard
import cy.hexor.furumi.domain.model.ConnectedPlaybackState
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -1,4 +1,4 @@
package com.example.furumi_android.ui.login
package cy.hexor.furumi.ui.login
import android.net.Uri
import androidx.browser.customtabs.CustomTabsIntent
@@ -30,15 +30,15 @@ import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import com.example.furumi_android.ui.theme.FurumiElectricCyan
import com.example.furumi_android.ui.theme.FurumiHotOrange
import com.example.furumi_android.ui.theme.FurumiInk
import com.example.furumi_android.ui.theme.FurumiLine
import com.example.furumi_android.ui.theme.FurumiNeonPink
import com.example.furumi_android.ui.theme.FurumiNeonViolet
import com.example.furumi_android.ui.theme.FurumiSurface
import com.example.furumi_android.ui.theme.FurumiSurfaceHigh
import com.example.furumi_android.ui.theme.FurumiTextMuted
import cy.hexor.furumi.ui.theme.FurumiElectricCyan
import cy.hexor.furumi.ui.theme.FurumiHotOrange
import cy.hexor.furumi.ui.theme.FurumiInk
import cy.hexor.furumi.ui.theme.FurumiLine
import cy.hexor.furumi.ui.theme.FurumiNeonPink
import cy.hexor.furumi.ui.theme.FurumiNeonViolet
import cy.hexor.furumi.ui.theme.FurumiSurface
import cy.hexor.furumi.ui.theme.FurumiSurfaceHigh
import cy.hexor.furumi.ui.theme.FurumiTextMuted
@Composable
fun LoginScreen(
@@ -1,10 +1,10 @@
package com.example.furumi_android.ui.login
package cy.hexor.furumi.ui.login
import android.net.Uri
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.furumi_android.domain.model.ServerConfig
import com.example.furumi_android.domain.repository.AuthRepository
import cy.hexor.furumi.domain.model.ServerConfig
import cy.hexor.furumi.domain.repository.AuthRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
@@ -1,4 +1,4 @@
package com.example.furumi_android.ui.player
package cy.hexor.furumi.ui.player
import android.content.Intent
import android.graphics.Bitmap
@@ -58,21 +58,21 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import com.example.furumi_android.domain.model.ArtistCard
import com.example.furumi_android.domain.model.PlaylistCard
import com.example.furumi_android.domain.model.ReleaseCard
import com.example.furumi_android.domain.model.TrackCard
import com.example.furumi_android.domain.model.ListeningHistoryItem
import com.example.furumi_android.playback.AudioPlaybackState
import com.example.furumi_android.ui.theme.FurumiBlack
import com.example.furumi_android.ui.theme.FurumiElectricCyan
import com.example.furumi_android.ui.theme.FurumiHotOrange
import com.example.furumi_android.ui.theme.FurumiLine
import com.example.furumi_android.ui.theme.FurumiNeonPink
import com.example.furumi_android.ui.theme.FurumiNeonViolet
import com.example.furumi_android.ui.theme.FurumiSurface
import com.example.furumi_android.ui.theme.FurumiSurfaceHigh
import com.example.furumi_android.ui.theme.FurumiTextMuted
import cy.hexor.furumi.domain.model.ArtistCard
import cy.hexor.furumi.domain.model.PlaylistCard
import cy.hexor.furumi.domain.model.ReleaseCard
import cy.hexor.furumi.domain.model.TrackCard
import cy.hexor.furumi.domain.model.ListeningHistoryItem
import cy.hexor.furumi.playback.AudioPlaybackState
import cy.hexor.furumi.ui.theme.FurumiBlack
import cy.hexor.furumi.ui.theme.FurumiElectricCyan
import cy.hexor.furumi.ui.theme.FurumiHotOrange
import cy.hexor.furumi.ui.theme.FurumiLine
import cy.hexor.furumi.ui.theme.FurumiNeonPink
import cy.hexor.furumi.ui.theme.FurumiNeonViolet
import cy.hexor.furumi.ui.theme.FurumiSurface
import cy.hexor.furumi.ui.theme.FurumiSurfaceHigh
import cy.hexor.furumi.ui.theme.FurumiTextMuted
import kotlin.math.roundToInt
@Composable
@@ -1,4 +1,4 @@
package com.example.furumi_android.ui.player
package cy.hexor.furumi.ui.player
import android.content.Intent
import android.graphics.Bitmap
@@ -58,22 +58,22 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import com.example.furumi_android.domain.model.ArtistCard
import com.example.furumi_android.domain.model.ConnectedDevice
import com.example.furumi_android.domain.model.PlaylistCard
import com.example.furumi_android.domain.model.ReleaseCard
import com.example.furumi_android.domain.model.TrackCard
import com.example.furumi_android.domain.model.ListeningHistoryItem
import com.example.furumi_android.playback.AudioPlaybackState
import com.example.furumi_android.ui.theme.FurumiBlack
import com.example.furumi_android.ui.theme.FurumiElectricCyan
import com.example.furumi_android.ui.theme.FurumiHotOrange
import com.example.furumi_android.ui.theme.FurumiLine
import com.example.furumi_android.ui.theme.FurumiNeonPink
import com.example.furumi_android.ui.theme.FurumiNeonViolet
import com.example.furumi_android.ui.theme.FurumiSurface
import com.example.furumi_android.ui.theme.FurumiSurfaceHigh
import com.example.furumi_android.ui.theme.FurumiTextMuted
import cy.hexor.furumi.domain.model.ArtistCard
import cy.hexor.furumi.domain.model.ConnectedDevice
import cy.hexor.furumi.domain.model.PlaylistCard
import cy.hexor.furumi.domain.model.ReleaseCard
import cy.hexor.furumi.domain.model.TrackCard
import cy.hexor.furumi.domain.model.ListeningHistoryItem
import cy.hexor.furumi.playback.AudioPlaybackState
import cy.hexor.furumi.ui.theme.FurumiBlack
import cy.hexor.furumi.ui.theme.FurumiElectricCyan
import cy.hexor.furumi.ui.theme.FurumiHotOrange
import cy.hexor.furumi.ui.theme.FurumiLine
import cy.hexor.furumi.ui.theme.FurumiNeonPink
import cy.hexor.furumi.ui.theme.FurumiNeonViolet
import cy.hexor.furumi.ui.theme.FurumiSurface
import cy.hexor.furumi.ui.theme.FurumiSurfaceHigh
import cy.hexor.furumi.ui.theme.FurumiTextMuted
import kotlin.math.roundToInt
@Composable
@@ -1,4 +1,4 @@
package com.example.furumi_android.ui.player
package cy.hexor.furumi.ui.player
import android.content.Intent
import android.graphics.Bitmap
@@ -58,21 +58,21 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import com.example.furumi_android.domain.model.ArtistCard
import com.example.furumi_android.domain.model.PlaylistCard
import com.example.furumi_android.domain.model.ReleaseCard
import com.example.furumi_android.domain.model.TrackCard
import com.example.furumi_android.domain.model.ListeningHistoryItem
import com.example.furumi_android.playback.AudioPlaybackState
import com.example.furumi_android.ui.theme.FurumiBlack
import com.example.furumi_android.ui.theme.FurumiElectricCyan
import com.example.furumi_android.ui.theme.FurumiHotOrange
import com.example.furumi_android.ui.theme.FurumiLine
import com.example.furumi_android.ui.theme.FurumiNeonPink
import com.example.furumi_android.ui.theme.FurumiNeonViolet
import com.example.furumi_android.ui.theme.FurumiSurface
import com.example.furumi_android.ui.theme.FurumiSurfaceHigh
import com.example.furumi_android.ui.theme.FurumiTextMuted
import cy.hexor.furumi.domain.model.ArtistCard
import cy.hexor.furumi.domain.model.PlaylistCard
import cy.hexor.furumi.domain.model.ReleaseCard
import cy.hexor.furumi.domain.model.TrackCard
import cy.hexor.furumi.domain.model.ListeningHistoryItem
import cy.hexor.furumi.playback.AudioPlaybackState
import cy.hexor.furumi.ui.theme.FurumiBlack
import cy.hexor.furumi.ui.theme.FurumiElectricCyan
import cy.hexor.furumi.ui.theme.FurumiHotOrange
import cy.hexor.furumi.ui.theme.FurumiLine
import cy.hexor.furumi.ui.theme.FurumiNeonPink
import cy.hexor.furumi.ui.theme.FurumiNeonViolet
import cy.hexor.furumi.ui.theme.FurumiSurface
import cy.hexor.furumi.ui.theme.FurumiSurfaceHigh
import cy.hexor.furumi.ui.theme.FurumiTextMuted
import kotlin.math.roundToInt
@Composable
@@ -1,4 +1,4 @@
package com.example.furumi_android.ui.player
package cy.hexor.furumi.ui.player
import android.content.Intent
import android.graphics.Bitmap
@@ -58,21 +58,21 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import com.example.furumi_android.domain.model.ArtistCard
import com.example.furumi_android.domain.model.PlaylistCard
import com.example.furumi_android.domain.model.ReleaseCard
import com.example.furumi_android.domain.model.TrackCard
import com.example.furumi_android.domain.model.ListeningHistoryItem
import com.example.furumi_android.playback.AudioPlaybackState
import com.example.furumi_android.ui.theme.FurumiBlack
import com.example.furumi_android.ui.theme.FurumiElectricCyan
import com.example.furumi_android.ui.theme.FurumiHotOrange
import com.example.furumi_android.ui.theme.FurumiLine
import com.example.furumi_android.ui.theme.FurumiNeonPink
import com.example.furumi_android.ui.theme.FurumiNeonViolet
import com.example.furumi_android.ui.theme.FurumiSurface
import com.example.furumi_android.ui.theme.FurumiSurfaceHigh
import com.example.furumi_android.ui.theme.FurumiTextMuted
import cy.hexor.furumi.domain.model.ArtistCard
import cy.hexor.furumi.domain.model.PlaylistCard
import cy.hexor.furumi.domain.model.ReleaseCard
import cy.hexor.furumi.domain.model.TrackCard
import cy.hexor.furumi.domain.model.ListeningHistoryItem
import cy.hexor.furumi.playback.AudioPlaybackState
import cy.hexor.furumi.ui.theme.FurumiBlack
import cy.hexor.furumi.ui.theme.FurumiElectricCyan
import cy.hexor.furumi.ui.theme.FurumiHotOrange
import cy.hexor.furumi.ui.theme.FurumiLine
import cy.hexor.furumi.ui.theme.FurumiNeonPink
import cy.hexor.furumi.ui.theme.FurumiNeonViolet
import cy.hexor.furumi.ui.theme.FurumiSurface
import cy.hexor.furumi.ui.theme.FurumiSurfaceHigh
import cy.hexor.furumi.ui.theme.FurumiTextMuted
import kotlin.math.roundToInt
@Composable
@@ -1,4 +1,4 @@
package com.example.furumi_android.ui.player
package cy.hexor.furumi.ui.player
import android.content.Intent
import android.graphics.Bitmap
@@ -58,21 +58,21 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import com.example.furumi_android.domain.model.ArtistCard
import com.example.furumi_android.domain.model.PlaylistCard
import com.example.furumi_android.domain.model.ReleaseCard
import com.example.furumi_android.domain.model.TrackCard
import com.example.furumi_android.domain.model.ListeningHistoryItem
import com.example.furumi_android.playback.AudioPlaybackState
import com.example.furumi_android.ui.theme.FurumiBlack
import com.example.furumi_android.ui.theme.FurumiElectricCyan
import com.example.furumi_android.ui.theme.FurumiHotOrange
import com.example.furumi_android.ui.theme.FurumiLine
import com.example.furumi_android.ui.theme.FurumiNeonPink
import com.example.furumi_android.ui.theme.FurumiNeonViolet
import com.example.furumi_android.ui.theme.FurumiSurface
import com.example.furumi_android.ui.theme.FurumiSurfaceHigh
import com.example.furumi_android.ui.theme.FurumiTextMuted
import cy.hexor.furumi.domain.model.ArtistCard
import cy.hexor.furumi.domain.model.PlaylistCard
import cy.hexor.furumi.domain.model.ReleaseCard
import cy.hexor.furumi.domain.model.TrackCard
import cy.hexor.furumi.domain.model.ListeningHistoryItem
import cy.hexor.furumi.playback.AudioPlaybackState
import cy.hexor.furumi.ui.theme.FurumiBlack
import cy.hexor.furumi.ui.theme.FurumiElectricCyan
import cy.hexor.furumi.ui.theme.FurumiHotOrange
import cy.hexor.furumi.ui.theme.FurumiLine
import cy.hexor.furumi.ui.theme.FurumiNeonPink
import cy.hexor.furumi.ui.theme.FurumiNeonViolet
import cy.hexor.furumi.ui.theme.FurumiSurface
import cy.hexor.furumi.ui.theme.FurumiSurfaceHigh
import cy.hexor.furumi.ui.theme.FurumiTextMuted
import kotlin.math.roundToInt
@Composable
@@ -1,4 +1,4 @@
package com.example.furumi_android.ui.player
package cy.hexor.furumi.ui.player
import android.content.Intent
import android.graphics.Bitmap
@@ -59,21 +59,21 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import com.example.furumi_android.domain.model.ArtistCard
import com.example.furumi_android.domain.model.PlaylistCard
import com.example.furumi_android.domain.model.ReleaseCard
import com.example.furumi_android.domain.model.TrackCard
import com.example.furumi_android.domain.model.ListeningHistoryItem
import com.example.furumi_android.playback.AudioPlaybackState
import com.example.furumi_android.ui.theme.FurumiBlack
import com.example.furumi_android.ui.theme.FurumiElectricCyan
import com.example.furumi_android.ui.theme.FurumiHotOrange
import com.example.furumi_android.ui.theme.FurumiLine
import com.example.furumi_android.ui.theme.FurumiNeonPink
import com.example.furumi_android.ui.theme.FurumiNeonViolet
import com.example.furumi_android.ui.theme.FurumiSurface
import com.example.furumi_android.ui.theme.FurumiSurfaceHigh
import com.example.furumi_android.ui.theme.FurumiTextMuted
import cy.hexor.furumi.domain.model.ArtistCard
import cy.hexor.furumi.domain.model.PlaylistCard
import cy.hexor.furumi.domain.model.ReleaseCard
import cy.hexor.furumi.domain.model.TrackCard
import cy.hexor.furumi.domain.model.ListeningHistoryItem
import cy.hexor.furumi.playback.AudioPlaybackState
import cy.hexor.furumi.ui.theme.FurumiBlack
import cy.hexor.furumi.ui.theme.FurumiElectricCyan
import cy.hexor.furumi.ui.theme.FurumiHotOrange
import cy.hexor.furumi.ui.theme.FurumiLine
import cy.hexor.furumi.ui.theme.FurumiNeonPink
import cy.hexor.furumi.ui.theme.FurumiNeonViolet
import cy.hexor.furumi.ui.theme.FurumiSurface
import cy.hexor.furumi.ui.theme.FurumiSurfaceHigh
import cy.hexor.furumi.ui.theme.FurumiTextMuted
import kotlin.math.roundToInt
@Composable
@@ -1,4 +1,4 @@
package com.example.furumi_android.ui.player
package cy.hexor.furumi.ui.player
import android.content.Intent
import android.graphics.Bitmap
@@ -58,21 +58,21 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import com.example.furumi_android.domain.model.ArtistCard
import com.example.furumi_android.domain.model.PlaylistCard
import com.example.furumi_android.domain.model.ReleaseCard
import com.example.furumi_android.domain.model.TrackCard
import com.example.furumi_android.domain.model.ListeningHistoryItem
import com.example.furumi_android.playback.AudioPlaybackState
import com.example.furumi_android.ui.theme.FurumiBlack
import com.example.furumi_android.ui.theme.FurumiElectricCyan
import com.example.furumi_android.ui.theme.FurumiHotOrange
import com.example.furumi_android.ui.theme.FurumiLine
import com.example.furumi_android.ui.theme.FurumiNeonPink
import com.example.furumi_android.ui.theme.FurumiNeonViolet
import com.example.furumi_android.ui.theme.FurumiSurface
import com.example.furumi_android.ui.theme.FurumiSurfaceHigh
import com.example.furumi_android.ui.theme.FurumiTextMuted
import cy.hexor.furumi.domain.model.ArtistCard
import cy.hexor.furumi.domain.model.PlaylistCard
import cy.hexor.furumi.domain.model.ReleaseCard
import cy.hexor.furumi.domain.model.TrackCard
import cy.hexor.furumi.domain.model.ListeningHistoryItem
import cy.hexor.furumi.playback.AudioPlaybackState
import cy.hexor.furumi.ui.theme.FurumiBlack
import cy.hexor.furumi.ui.theme.FurumiElectricCyan
import cy.hexor.furumi.ui.theme.FurumiHotOrange
import cy.hexor.furumi.ui.theme.FurumiLine
import cy.hexor.furumi.ui.theme.FurumiNeonPink
import cy.hexor.furumi.ui.theme.FurumiNeonViolet
import cy.hexor.furumi.ui.theme.FurumiSurface
import cy.hexor.furumi.ui.theme.FurumiSurfaceHigh
import cy.hexor.furumi.ui.theme.FurumiTextMuted
import kotlin.math.roundToInt
@Composable
@@ -1,4 +1,4 @@
package com.example.furumi_android.ui.player
package cy.hexor.furumi.ui.player
import android.content.Intent
import android.graphics.Bitmap
@@ -58,21 +58,21 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import com.example.furumi_android.domain.model.ArtistCard
import com.example.furumi_android.domain.model.PlaylistCard
import com.example.furumi_android.domain.model.ReleaseCard
import com.example.furumi_android.domain.model.TrackCard
import com.example.furumi_android.domain.model.ListeningHistoryItem
import com.example.furumi_android.playback.AudioPlaybackState
import com.example.furumi_android.ui.theme.FurumiBlack
import com.example.furumi_android.ui.theme.FurumiElectricCyan
import com.example.furumi_android.ui.theme.FurumiHotOrange
import com.example.furumi_android.ui.theme.FurumiLine
import com.example.furumi_android.ui.theme.FurumiNeonPink
import com.example.furumi_android.ui.theme.FurumiNeonViolet
import com.example.furumi_android.ui.theme.FurumiSurface
import com.example.furumi_android.ui.theme.FurumiSurfaceHigh
import com.example.furumi_android.ui.theme.FurumiTextMuted
import cy.hexor.furumi.domain.model.ArtistCard
import cy.hexor.furumi.domain.model.PlaylistCard
import cy.hexor.furumi.domain.model.ReleaseCard
import cy.hexor.furumi.domain.model.TrackCard
import cy.hexor.furumi.domain.model.ListeningHistoryItem
import cy.hexor.furumi.playback.AudioPlaybackState
import cy.hexor.furumi.ui.theme.FurumiBlack
import cy.hexor.furumi.ui.theme.FurumiElectricCyan
import cy.hexor.furumi.ui.theme.FurumiHotOrange
import cy.hexor.furumi.ui.theme.FurumiLine
import cy.hexor.furumi.ui.theme.FurumiNeonPink
import cy.hexor.furumi.ui.theme.FurumiNeonViolet
import cy.hexor.furumi.ui.theme.FurumiSurface
import cy.hexor.furumi.ui.theme.FurumiSurfaceHigh
import cy.hexor.furumi.ui.theme.FurumiTextMuted
import kotlin.math.roundToInt
internal enum class PlayerTab(
@@ -1,4 +1,4 @@
package com.example.furumi_android.ui.player
package cy.hexor.furumi.ui.player
import android.content.Intent
import android.graphics.Bitmap
@@ -59,25 +59,25 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import com.example.furumi_android.domain.model.ArtistCard
import com.example.furumi_android.domain.model.ConnectedDevice
import com.example.furumi_android.domain.model.ConnectedDevicesState
import com.example.furumi_android.domain.model.ConnectedJam
import com.example.furumi_android.domain.model.ConnectedJamUser
import com.example.furumi_android.domain.model.PlaylistCard
import com.example.furumi_android.domain.model.ReleaseCard
import com.example.furumi_android.domain.model.TrackCard
import com.example.furumi_android.domain.model.ListeningHistoryItem
import com.example.furumi_android.playback.AudioPlaybackState
import com.example.furumi_android.ui.theme.FurumiBlack
import com.example.furumi_android.ui.theme.FurumiElectricCyan
import com.example.furumi_android.ui.theme.FurumiHotOrange
import com.example.furumi_android.ui.theme.FurumiLine
import com.example.furumi_android.ui.theme.FurumiNeonPink
import com.example.furumi_android.ui.theme.FurumiNeonViolet
import com.example.furumi_android.ui.theme.FurumiSurface
import com.example.furumi_android.ui.theme.FurumiSurfaceHigh
import com.example.furumi_android.ui.theme.FurumiTextMuted
import cy.hexor.furumi.domain.model.ArtistCard
import cy.hexor.furumi.domain.model.ConnectedDevice
import cy.hexor.furumi.domain.model.ConnectedDevicesState
import cy.hexor.furumi.domain.model.ConnectedJam
import cy.hexor.furumi.domain.model.ConnectedJamUser
import cy.hexor.furumi.domain.model.PlaylistCard
import cy.hexor.furumi.domain.model.ReleaseCard
import cy.hexor.furumi.domain.model.TrackCard
import cy.hexor.furumi.domain.model.ListeningHistoryItem
import cy.hexor.furumi.playback.AudioPlaybackState
import cy.hexor.furumi.ui.theme.FurumiBlack
import cy.hexor.furumi.ui.theme.FurumiElectricCyan
import cy.hexor.furumi.ui.theme.FurumiHotOrange
import cy.hexor.furumi.ui.theme.FurumiLine
import cy.hexor.furumi.ui.theme.FurumiNeonPink
import cy.hexor.furumi.ui.theme.FurumiNeonViolet
import cy.hexor.furumi.ui.theme.FurumiSurface
import cy.hexor.furumi.ui.theme.FurumiSurfaceHigh
import cy.hexor.furumi.ui.theme.FurumiTextMuted
import kotlin.math.roundToInt
@Composable
@@ -100,7 +100,7 @@ internal fun FullPlayerOverlay(
onPlayLast: (TrackCard) -> Unit,
onShare: (TrackCard) -> Unit,
onAddToPlaylist: (TrackCard) -> Unit,
onArtistClick: (com.example.furumi_android.domain.model.ArtistCard) -> Unit,
onArtistClick: (cy.hexor.furumi.domain.model.ArtistCard) -> Unit,
connectedDevicesState: ConnectedDevicesState?,
connectedDevicesError: String?,
onDeviceClick: (String) -> Unit,
@@ -275,7 +275,7 @@ internal fun FullPlayerOverlay(
)
val artists = track.artistRefs.ifEmpty {
track.artists.mapIndexed { i, name -> com.example.furumi_android.domain.model.ArtistRef(id = -(i + 1L), name = name) }
track.artists.mapIndexed { i, name -> cy.hexor.furumi.domain.model.ArtistRef(id = -(i + 1L), name = name) }
}
Row(
@@ -291,7 +291,7 @@ internal fun FullPlayerOverlay(
overflow = TextOverflow.Ellipsis,
modifier = Modifier.clickable(enabled = artistRef.id > 0) {
onArtistClick(
com.example.furumi_android.domain.model.ArtistCard(
cy.hexor.furumi.domain.model.ArtistCard(
id = artistRef.id,
name = artistRef.name,
imageUrl = null,
@@ -1,4 +1,4 @@
package com.example.furumi_android.ui.player
package cy.hexor.furumi.ui.player
import android.content.Intent
import android.graphics.Bitmap
@@ -58,21 +58,21 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import com.example.furumi_android.domain.model.ArtistCard
import com.example.furumi_android.domain.model.PlaylistCard
import com.example.furumi_android.domain.model.ReleaseCard
import com.example.furumi_android.domain.model.TrackCard
import com.example.furumi_android.domain.model.ListeningHistoryItem
import com.example.furumi_android.playback.AudioPlaybackState
import com.example.furumi_android.ui.theme.FurumiBlack
import com.example.furumi_android.ui.theme.FurumiElectricCyan
import com.example.furumi_android.ui.theme.FurumiHotOrange
import com.example.furumi_android.ui.theme.FurumiLine
import com.example.furumi_android.ui.theme.FurumiNeonPink
import com.example.furumi_android.ui.theme.FurumiNeonViolet
import com.example.furumi_android.ui.theme.FurumiSurface
import com.example.furumi_android.ui.theme.FurumiSurfaceHigh
import com.example.furumi_android.ui.theme.FurumiTextMuted
import cy.hexor.furumi.domain.model.ArtistCard
import cy.hexor.furumi.domain.model.PlaylistCard
import cy.hexor.furumi.domain.model.ReleaseCard
import cy.hexor.furumi.domain.model.TrackCard
import cy.hexor.furumi.domain.model.ListeningHistoryItem
import cy.hexor.furumi.playback.AudioPlaybackState
import cy.hexor.furumi.ui.theme.FurumiBlack
import cy.hexor.furumi.ui.theme.FurumiElectricCyan
import cy.hexor.furumi.ui.theme.FurumiHotOrange
import cy.hexor.furumi.ui.theme.FurumiLine
import cy.hexor.furumi.ui.theme.FurumiNeonPink
import cy.hexor.furumi.ui.theme.FurumiNeonViolet
import cy.hexor.furumi.ui.theme.FurumiSurface
import cy.hexor.furumi.ui.theme.FurumiSurfaceHigh
import cy.hexor.furumi.ui.theme.FurumiTextMuted
import kotlin.math.roundToInt
@Composable
@@ -1,4 +1,4 @@
package com.example.furumi_android.ui.player
package cy.hexor.furumi.ui.player
import android.content.Intent
import android.graphics.Bitmap
@@ -61,21 +61,21 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import com.example.furumi_android.domain.model.ArtistCard
import com.example.furumi_android.domain.model.PlaylistCard
import com.example.furumi_android.domain.model.ReleaseCard
import com.example.furumi_android.domain.model.TrackCard
import com.example.furumi_android.domain.model.ListeningHistoryItem
import com.example.furumi_android.playback.AudioPlaybackState
import com.example.furumi_android.ui.theme.FurumiBlack
import com.example.furumi_android.ui.theme.FurumiElectricCyan
import com.example.furumi_android.ui.theme.FurumiHotOrange
import com.example.furumi_android.ui.theme.FurumiLine
import com.example.furumi_android.ui.theme.FurumiNeonPink
import com.example.furumi_android.ui.theme.FurumiNeonViolet
import com.example.furumi_android.ui.theme.FurumiSurface
import com.example.furumi_android.ui.theme.FurumiSurfaceHigh
import com.example.furumi_android.ui.theme.FurumiTextMuted
import cy.hexor.furumi.domain.model.ArtistCard
import cy.hexor.furumi.domain.model.PlaylistCard
import cy.hexor.furumi.domain.model.ReleaseCard
import cy.hexor.furumi.domain.model.TrackCard
import cy.hexor.furumi.domain.model.ListeningHistoryItem
import cy.hexor.furumi.playback.AudioPlaybackState
import cy.hexor.furumi.ui.theme.FurumiBlack
import cy.hexor.furumi.ui.theme.FurumiElectricCyan
import cy.hexor.furumi.ui.theme.FurumiHotOrange
import cy.hexor.furumi.ui.theme.FurumiLine
import cy.hexor.furumi.ui.theme.FurumiNeonPink
import cy.hexor.furumi.ui.theme.FurumiNeonViolet
import cy.hexor.furumi.ui.theme.FurumiSurface
import cy.hexor.furumi.ui.theme.FurumiSurfaceHigh
import cy.hexor.furumi.ui.theme.FurumiTextMuted
import kotlin.math.roundToInt
@Composable
@@ -1,4 +1,4 @@
package com.example.furumi_android.ui.player
package cy.hexor.furumi.ui.player
import android.content.Intent
import android.graphics.Bitmap
@@ -58,23 +58,23 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import com.example.furumi_android.domain.model.ArtistCard
import com.example.furumi_android.domain.model.ConnectedDevicesState
import com.example.furumi_android.domain.model.ConnectedPlaybackState
import com.example.furumi_android.domain.model.PlaylistCard
import com.example.furumi_android.domain.model.ReleaseCard
import com.example.furumi_android.domain.model.TrackCard
import com.example.furumi_android.domain.model.ListeningHistoryItem
import com.example.furumi_android.playback.AudioPlaybackState
import com.example.furumi_android.ui.theme.FurumiBlack
import com.example.furumi_android.ui.theme.FurumiElectricCyan
import com.example.furumi_android.ui.theme.FurumiHotOrange
import com.example.furumi_android.ui.theme.FurumiLine
import com.example.furumi_android.ui.theme.FurumiNeonPink
import com.example.furumi_android.ui.theme.FurumiNeonViolet
import com.example.furumi_android.ui.theme.FurumiSurface
import com.example.furumi_android.ui.theme.FurumiSurfaceHigh
import com.example.furumi_android.ui.theme.FurumiTextMuted
import cy.hexor.furumi.domain.model.ArtistCard
import cy.hexor.furumi.domain.model.ConnectedDevicesState
import cy.hexor.furumi.domain.model.ConnectedPlaybackState
import cy.hexor.furumi.domain.model.PlaylistCard
import cy.hexor.furumi.domain.model.ReleaseCard
import cy.hexor.furumi.domain.model.TrackCard
import cy.hexor.furumi.domain.model.ListeningHistoryItem
import cy.hexor.furumi.playback.AudioPlaybackState
import cy.hexor.furumi.ui.theme.FurumiBlack
import cy.hexor.furumi.ui.theme.FurumiElectricCyan
import cy.hexor.furumi.ui.theme.FurumiHotOrange
import cy.hexor.furumi.ui.theme.FurumiLine
import cy.hexor.furumi.ui.theme.FurumiNeonPink
import cy.hexor.furumi.ui.theme.FurumiNeonViolet
import cy.hexor.furumi.ui.theme.FurumiSurface
import cy.hexor.furumi.ui.theme.FurumiSurfaceHigh
import cy.hexor.furumi.ui.theme.FurumiTextMuted
import kotlin.math.roundToInt
@Composable
@@ -1,4 +1,4 @@
package com.example.furumi_android.ui.player
package cy.hexor.furumi.ui.player
import android.content.Intent
import android.graphics.Bitmap
@@ -58,21 +58,21 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import com.example.furumi_android.domain.model.ArtistCard
import com.example.furumi_android.domain.model.PlaylistCard
import com.example.furumi_android.domain.model.ReleaseCard
import com.example.furumi_android.domain.model.TrackCard
import com.example.furumi_android.domain.model.ListeningHistoryItem
import com.example.furumi_android.playback.AudioPlaybackState
import com.example.furumi_android.ui.theme.FurumiBlack
import com.example.furumi_android.ui.theme.FurumiElectricCyan
import com.example.furumi_android.ui.theme.FurumiHotOrange
import com.example.furumi_android.ui.theme.FurumiLine
import com.example.furumi_android.ui.theme.FurumiNeonPink
import com.example.furumi_android.ui.theme.FurumiNeonViolet
import com.example.furumi_android.ui.theme.FurumiSurface
import com.example.furumi_android.ui.theme.FurumiSurfaceHigh
import com.example.furumi_android.ui.theme.FurumiTextMuted
import cy.hexor.furumi.domain.model.ArtistCard
import cy.hexor.furumi.domain.model.PlaylistCard
import cy.hexor.furumi.domain.model.ReleaseCard
import cy.hexor.furumi.domain.model.TrackCard
import cy.hexor.furumi.domain.model.ListeningHistoryItem
import cy.hexor.furumi.playback.AudioPlaybackState
import cy.hexor.furumi.ui.theme.FurumiBlack
import cy.hexor.furumi.ui.theme.FurumiElectricCyan
import cy.hexor.furumi.ui.theme.FurumiHotOrange
import cy.hexor.furumi.ui.theme.FurumiLine
import cy.hexor.furumi.ui.theme.FurumiNeonPink
import cy.hexor.furumi.ui.theme.FurumiNeonViolet
import cy.hexor.furumi.ui.theme.FurumiSurface
import cy.hexor.furumi.ui.theme.FurumiSurfaceHigh
import cy.hexor.furumi.ui.theme.FurumiTextMuted
import kotlin.math.roundToInt
internal fun artistsSubtitle(uiState: PlayerUiState): String {
@@ -1,27 +1,27 @@
package com.example.furumi_android.ui.player
package cy.hexor.furumi.ui.player
import android.graphics.Bitmap
import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.furumi_android.data.repository.MediaImageLoader
import com.example.furumi_android.domain.model.ArtistCard
import com.example.furumi_android.domain.model.ArtistDetail
import com.example.furumi_android.domain.model.ConnectedCommand
import com.example.furumi_android.domain.model.ConnectedDevicesState
import com.example.furumi_android.domain.model.ConnectedJamUser
import com.example.furumi_android.domain.model.ConnectedPlaybackState
import com.example.furumi_android.domain.model.ListeningHistoryItem
import com.example.furumi_android.domain.model.PlaylistCard
import com.example.furumi_android.domain.model.PlaylistDetail
import com.example.furumi_android.domain.model.ReleaseCard
import com.example.furumi_android.domain.model.ReleaseDetail
import com.example.furumi_android.domain.model.SearchResults
import com.example.furumi_android.domain.model.TrackCard
import com.example.furumi_android.domain.repository.AuthRepository
import com.example.furumi_android.domain.repository.PlayerRepository
import com.example.furumi_android.playback.AudioPlaybackState
import com.example.furumi_android.playback.PlaybackController
import cy.hexor.furumi.data.repository.MediaImageLoader
import cy.hexor.furumi.domain.model.ArtistCard
import cy.hexor.furumi.domain.model.ArtistDetail
import cy.hexor.furumi.domain.model.ConnectedCommand
import cy.hexor.furumi.domain.model.ConnectedDevicesState
import cy.hexor.furumi.domain.model.ConnectedJamUser
import cy.hexor.furumi.domain.model.ConnectedPlaybackState
import cy.hexor.furumi.domain.model.ListeningHistoryItem
import cy.hexor.furumi.domain.model.PlaylistCard
import cy.hexor.furumi.domain.model.PlaylistDetail
import cy.hexor.furumi.domain.model.ReleaseCard
import cy.hexor.furumi.domain.model.ReleaseDetail
import cy.hexor.furumi.domain.model.SearchResults
import cy.hexor.furumi.domain.model.TrackCard
import cy.hexor.furumi.domain.repository.AuthRepository
import cy.hexor.furumi.domain.repository.PlayerRepository
import cy.hexor.furumi.playback.AudioPlaybackState
import cy.hexor.furumi.playback.PlaybackController
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -95,7 +95,7 @@ class PlayerViewModel @Inject constructor(
private val playerRepository: PlayerRepository,
private val mediaImageLoader: MediaImageLoader,
private val playbackController: PlaybackController,
appClientInfo: com.example.furumi_android.data.remote.AppClientInfo
appClientInfo: cy.hexor.furumi.data.remote.AppClientInfo
) : ViewModel() {
private val artistDetailCache = mutableMapOf<Long, ArtistDetail>()
@@ -1,4 +1,4 @@
package com.example.furumi_android.ui.profile
package cy.hexor.furumi.ui.profile
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
@@ -1,9 +1,9 @@
package com.example.furumi_android.ui.profile
package cy.hexor.furumi.ui.profile
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.furumi_android.domain.model.User
import com.example.furumi_android.domain.repository.AuthRepository
import cy.hexor.furumi.domain.model.User
import cy.hexor.furumi.domain.repository.AuthRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
@@ -1,4 +1,4 @@
package com.example.furumi_android.ui.theme
package cy.hexor.furumi.ui.theme
import androidx.compose.ui.graphics.Color
@@ -1,4 +1,4 @@
package com.example.furumi_android.ui.theme
package cy.hexor.furumi.ui.theme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
@@ -1,4 +1,4 @@
package com.example.furumi_android.ui.theme
package cy.hexor.furumi.ui.theme
import androidx.compose.material3.Typography
import androidx.compose.ui.text.TextStyle
@@ -1,4 +1,4 @@
package com.example.furumi_android
package cy.hexor.furumi
import org.junit.Test
@@ -1,4 +1,4 @@
package com.example.furumi_android.domain.model
package cy.hexor.furumi.domain.model
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
+41
View File
@@ -0,0 +1,41 @@
Categories:
- Multimedia
License: WTFPL
AuthorName: ab
SourceCode: https://gt.hexor.cy/ab/furumi_android
IssueTracker: https://gt.hexor.cy/ab/furumi_android/issues
AutoName: Furumi
Description: |-
Furumi is an Android client for the Furumi self-hosted music streaming server.
Connect to your own Furumi instance and enjoy your personal music library from anywhere.
Features:
* Browse your music library — artists, albums, and tracks
* Full playback controls with background playback support
* Queue management and listening history
* Connect and control multiple remote devices
* Jam sessions — listen together with others
* Secure authentication with token-based sessions
* Material You design with edge-to-edge UI
Requires a running Furumi server instance to connect to.
RepoType: git
Repo: https://gt.hexor.cy/ab/furumi_android.git
Builds:
- versionName: '1.1'
versionCode: 1
commit: v1.1
subdir: app
gradle:
- yes
AutoUpdateMode: Version v%v
UpdateCheckMode: Tags
CurrentVersion: '1.1'
CurrentVersionCode: 1
@@ -0,0 +1 @@
Initial release.
@@ -0,0 +1,14 @@
Furumi is an Android client for the Furumi self-hosted music streaming server.
Connect to your own Furumi instance and enjoy your personal music library from anywhere.
Features:
* Browse your music library — artists, albums, and tracks
* Full playback controls with background playback support
* Queue management and listening history
* Connect and control multiple remote devices
* Jam sessions — listen together with others
* Secure authentication with token-based sessions
* Material You design with edge-to-edge UI
Furumi requires a running Furumi server instance to connect to.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

@@ -0,0 +1 @@
Android client for the Furumi self-hosted music streaming server
-3
View File
@@ -11,9 +11,6 @@ pluginManagement {
gradlePluginPortal()
}
}
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {