Merge branch 'master' into local-snapshot
# Conflicts: # app/src/main/kotlin/com/example/myapplication/MainApp.kt # app/src/main/kotlin/com/example/myapplication/screens/HomeScreen.kt # app/src/main/kotlin/com/example/myapplication/screens/LibraryScreen.kt # app/src/main/kotlin/com/example/myapplication/screens/RecordsScreen.kt
No files matched your search
@@ -12,7 +12,7 @@ android {
|
||||
minSdk = 24
|
||||
targetSdk = 35
|
||||
versionCode = 1
|
||||
versionName = "1.0"
|
||||
versionName = "1.0.0"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
|
||||
@@ -12,6 +12,7 @@ import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
@@ -46,6 +47,7 @@ import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.example.myapplication.R as Res
|
||||
import com.example.myapplication.data.EmbyRepository
|
||||
import com.example.myapplication.data.EmbyServer
|
||||
import com.example.myapplication.data.IconLibrary
|
||||
@@ -65,6 +67,7 @@ import com.example.myapplication.ui.AppTheme
|
||||
import com.example.myapplication.ui.GlassTokens
|
||||
import com.example.myapplication.ui.LiquidAppBottomBar
|
||||
import com.example.myapplication.ui.LiquidGlassBackground
|
||||
import com.kyant.backdrop.backdrops.layerBackdrop
|
||||
import com.kyant.backdrop.backdrops.rememberLayerBackdrop
|
||||
import dev.chrisbanes.haze.HazeState
|
||||
import dev.chrisbanes.haze.hazeSource
|
||||
@@ -81,7 +84,7 @@ fun MainApp() {
|
||||
var recordsSegment by remember { mutableIntStateOf(0) }
|
||||
var searchQuery by remember { mutableStateOf("") }
|
||||
var showLibraryAddDialog by remember { mutableStateOf(false) }
|
||||
var libraryIsGrid by remember { mutableStateOf(false) }
|
||||
var libraryIsGrid by remember { mutableStateOf(true) }
|
||||
var showIconLibraryManager by remember { mutableStateOf(false) }
|
||||
var showCacheDetail by remember { mutableStateOf(false) }
|
||||
var homeDetailVisible by remember { mutableStateOf(false) }
|
||||
@@ -249,6 +252,7 @@ fun MainApp() {
|
||||
showAddDialog = showLibraryAddDialog,
|
||||
onDismissAddDialog = { showLibraryAddDialog = false },
|
||||
isGrid = libraryIsGrid,
|
||||
showTopBar = false,
|
||||
onChangeIconTarget = changeIconTarget,
|
||||
onDismissChangeIcon = { changeIconTarget = null },
|
||||
onPickIcon = { server, iconUrl -> ServerRepository.setRuntimeIcon(server.id, iconUrl) },
|
||||
|
||||
@@ -57,7 +57,14 @@ object IconLibraryRepository {
|
||||
|
||||
suspend fun addLibrary(library: IconLibrary) {
|
||||
save(library)
|
||||
setRuntimeIcons(library.id, library.icons)
|
||||
if (library.icons.isNotEmpty()) {
|
||||
setRuntimeIcons(library.id, library.icons)
|
||||
cachedIcons[library.id] = library.icons
|
||||
saveIconsToCache(library.id, library.icons)
|
||||
withContext(Dispatchers.IO) {
|
||||
database?.iconLibraryDao()?.updateIconCount(library.id, library.icons.size)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun removeLibrary(id: String) {
|
||||
|
||||
@@ -513,7 +513,11 @@ fun HomeScreen(
|
||||
},
|
||||
label = "HomeLoadingTransition"
|
||||
) { isLoading ->
|
||||
if (isLoading) {
|
||||
if (activeServer == null) {
|
||||
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||
EmptyHomeState()
|
||||
}
|
||||
} else if (isLoading) {
|
||||
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||
CircularProgressIndicator(color = adaptiveAccent)
|
||||
}
|
||||
@@ -579,6 +583,25 @@ fun HomeScreen(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun EmptyHomeState() {
|
||||
Column(
|
||||
Modifier.fillMaxWidth().padding(horizontal = 24.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Box(
|
||||
Modifier.size(64.dp).clip(CircleShape).background(homeSecondaryColor().copy(alpha = 0.16f)),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Icon(Icons.Filled.PlayArrow, contentDescription = null, tint = homeSecondaryColor(), modifier = Modifier.size(32.dp))
|
||||
}
|
||||
Spacer(Modifier.height(16.dp))
|
||||
Text("没有可用的媒体库", color = homeSecondaryColor(), fontSize = 15.sp)
|
||||
Spacer(Modifier.height(6.dp))
|
||||
Text("请在资源库中添加服务器", color = homeSecondaryColor().copy(alpha = 0.72f), fontSize = 12.sp)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun HomeOverlayTopBar(name: String, iconUrl: String, modifier: Modifier = Modifier) {
|
||||
LiquidGlassTopBar(modifier) {
|
||||
|
||||
@@ -6,26 +6,21 @@ import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.statusBarsPadding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.grid.GridCells
|
||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
import androidx.compose.foundation.lazy.grid.items
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.draw.shadow
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
@@ -59,7 +54,7 @@ fun SearchTopBar(
|
||||
GlassSearchField(
|
||||
value = query,
|
||||
onValueChange = onQueryChange,
|
||||
placeholder = stringResource(Res.string.search_hint),
|
||||
placeholder = stringResource(Res.string.search_hint),
|
||||
onGearClick = onGearClick,
|
||||
)
|
||||
}
|
||||
@@ -67,7 +62,11 @@ fun SearchTopBar(
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SearchScreen(query: String) {
|
||||
fun SearchScreen(
|
||||
query: String,
|
||||
onQueryChange: (String) -> Unit = {},
|
||||
onGearClick: () -> Unit = {},
|
||||
) {
|
||||
val allMedia: List<MediaItem> = sampleMovies() + sampleTvShows()
|
||||
val results = remember(query) {
|
||||
val q = query.trim()
|
||||
@@ -76,71 +75,80 @@ fun SearchScreen(query: String) {
|
||||
}
|
||||
}
|
||||
|
||||
Column(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(horizontal = 16.dp, vertical = 16.dp),
|
||||
) {
|
||||
if (query.isBlank()) {
|
||||
Box(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(top = 80.dp),
|
||||
contentAlignment = Alignment.TopCenter,
|
||||
) {
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(10.dp),
|
||||
val bottomPadding = bottomBarContentPadding(90.dp).calculateBottomPadding()
|
||||
|
||||
Box(Modifier.fillMaxSize()) {
|
||||
// Content area (full size, same as HomeScreen)
|
||||
Box(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(horizontal = 16.dp)
|
||||
.padding(bottom = bottomPadding),
|
||||
) {
|
||||
if (query.isBlank()) {
|
||||
Box(
|
||||
Modifier.fillMaxSize(),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Box(
|
||||
Modifier
|
||||
.size(72.dp)
|
||||
.clip(CircleShape)
|
||||
.background(GlassTokens.glassFill)
|
||||
.border(1.dp, GlassTokens.glassBorder, CircleShape),
|
||||
contentAlignment = Alignment.Center,
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
androidx.compose.material3.Icon(
|
||||
imageVector = Icons.Outlined.Search,
|
||||
contentDescription = null,
|
||||
tint = GlassTokens.subtext2,
|
||||
modifier = Modifier.size(34.dp),
|
||||
)
|
||||
Box(
|
||||
Modifier
|
||||
.size(64.dp)
|
||||
.clip(CircleShape)
|
||||
.background(GlassTokens.glassFill)
|
||||
.border(1.dp, GlassTokens.glassBorder, CircleShape),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
androidx.compose.material3.Icon(
|
||||
imageVector = Icons.Outlined.Search,
|
||||
contentDescription = null,
|
||||
tint = GlassTokens.subtext2,
|
||||
modifier = Modifier.size(32.dp),
|
||||
)
|
||||
}
|
||||
Spacer(Modifier.height(16.dp))
|
||||
Text(text = stringResource(Res.string.search_title), color = GlassTokens.text, fontSize = 15.sp, fontWeight = FontWeight.SemiBold)
|
||||
Spacer(Modifier.height(6.dp))
|
||||
Text(text = stringResource(Res.string.search_empty_input), color = GlassTokens.subtext, fontSize = 12.sp)
|
||||
}
|
||||
Text(text = stringResource(Res.string.search_title), color = GlassTokens.text, fontSize = 16.sp, fontWeight = FontWeight.SemiBold)
|
||||
Text(text = stringResource(Res.string.search_empty_input), color = GlassTokens.subtext, fontSize = 13.sp)
|
||||
}
|
||||
}
|
||||
} else if (results.isEmpty()) {
|
||||
Box(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(top = 80.dp),
|
||||
contentAlignment = Alignment.TopCenter,
|
||||
) {
|
||||
Text(text = stringResource(Res.string.search_no_result_prefix) + "$query" + stringResource(Res.string.search_no_result_suffix), color = GlassTokens.subtext, fontSize = 14.sp)
|
||||
}
|
||||
} else {
|
||||
LazyVerticalGrid(
|
||||
columns = GridCells.Fixed(2),
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentPadding = PaddingValues(bottom = bottomBarContentPadding(86.dp).calculateBottomPadding()),
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
items(results) { item ->
|
||||
Box(Modifier.fillMaxWidth()) {
|
||||
PosterBox(
|
||||
colors = item.posterColors,
|
||||
title = item.title,
|
||||
subtitle = item.subtitle,
|
||||
height = 190.dp,
|
||||
)
|
||||
} else if (results.isEmpty()) {
|
||||
Box(
|
||||
Modifier.fillMaxSize(),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Text(text = stringResource(Res.string.search_no_result_prefix) + "$query" + stringResource(Res.string.search_no_result_suffix), color = GlassTokens.subtext, fontSize = 14.sp)
|
||||
}
|
||||
} else {
|
||||
LazyVerticalGrid(
|
||||
columns = GridCells.Fixed(2),
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentPadding = PaddingValues(bottom = bottomBarContentPadding(86.dp).calculateBottomPadding()),
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
items(results) { item ->
|
||||
Box(Modifier.fillMaxWidth()) {
|
||||
PosterBox(
|
||||
colors = item.posterColors,
|
||||
title = item.title,
|
||||
subtitle = item.subtitle,
|
||||
height = 190.dp,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Overlay top bar (same pattern as HomeScreen)
|
||||
SearchTopBar(
|
||||
query = query,
|
||||
onQueryChange = onQueryChange,
|
||||
onGearClick = onGearClick,
|
||||
modifier = Modifier.align(Alignment.TopCenter),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -14,7 +14,15 @@ import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Favorite
|
||||
import androidx.compose.material.icons.filled.Home
|
||||
import androidx.compose.material.icons.filled.Search
|
||||
import androidx.compose.material.icons.filled.Settings
|
||||
import androidx.compose.material.icons.filled.Storage
|
||||
import androidx.compose.material.icons.outlined.FavoriteBorder
|
||||
import androidx.compose.material.icons.outlined.Home
|
||||
import androidx.compose.material.icons.outlined.Settings
|
||||
import androidx.compose.material.icons.outlined.Storage
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -22,6 +30,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
@@ -34,6 +43,19 @@ import com.example.myapplication.ui.liquidglass.LocalLiquidBottomTabsPillValue
|
||||
import com.kyant.backdrop.Backdrop
|
||||
import top.yukonga.miuix.kmp.basic.Text
|
||||
|
||||
private data class MainTab(
|
||||
val selectedIcon: ImageVector,
|
||||
val unselectedIcon: ImageVector,
|
||||
val labelRes: Int,
|
||||
)
|
||||
|
||||
private val mainTabs = listOf(
|
||||
MainTab(Icons.Filled.Home, Icons.Outlined.Home, Res.string.nav_home),
|
||||
MainTab(Icons.Filled.Favorite, Icons.Outlined.FavoriteBorder, Res.string.nav_records),
|
||||
MainTab(Icons.Filled.Storage, Icons.Outlined.Storage, Res.string.nav_library),
|
||||
MainTab(Icons.Filled.Settings, Icons.Outlined.Settings, Res.string.nav_settings),
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun LiquidAppBottomBar(
|
||||
selectedTab: Int,
|
||||
|
||||
@@ -54,6 +54,14 @@ object AppLanguage {
|
||||
return context as? Activity
|
||||
}
|
||||
|
||||
fun getLocalizedContext(context: Context): Context {
|
||||
val tag = if (language == 0) "zh-CN" else "en"
|
||||
val locale = java.util.Locale.forLanguageTag(tag)
|
||||
val config = android.content.res.Configuration(context.resources.configuration)
|
||||
config.setLocale(locale)
|
||||
return context.createConfigurationContext(config)
|
||||
}
|
||||
|
||||
private fun preferences(context: Context): SharedPreferences {
|
||||
return context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
|
||||
}
|
||||
|
||||
@@ -40,6 +40,8 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
@@ -489,6 +491,9 @@ fun GlassDialog(
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
Dialog(onDismissRequest = onDismissRequest) {
|
||||
val dialogCtx = LocalContext.current
|
||||
val localizedCtx = remember(AppLanguage.language) { AppLanguage.getLocalizedContext(dialogCtx) }
|
||||
CompositionLocalProvider(LocalContext provides localizedCtx) {
|
||||
Box(
|
||||
modifier
|
||||
.width(IntrinsicSize.Min)
|
||||
@@ -498,6 +503,7 @@ fun GlassDialog(
|
||||
) {
|
||||
content()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,167 +4,15 @@
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
|
||||
<!-- Dark purple-blue gradient background -->
|
||||
<path
|
||||
android:fillColor="#3DDC84"
|
||||
android:fillColor="#FF191932"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
|
||||
<!-- Subtle inner glow -->
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
android:fillColor="#1A321946"
|
||||
android:pathData="M54,54m-36,0a36,36 0,1 1,72 0a36,36 0,1 1,-72 0" />
|
||||
|
||||
</vector>
|
||||
@@ -1,30 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="85.84757"
|
||||
android:endY="92.4963"
|
||||
android:startX="42.9492"
|
||||
android:startY="49.59793"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
|
||||
<!-- White play circle centered at (54,54), radius 22dp -->
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000" />
|
||||
</vector>
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M54,54m-22,0a22,22 0,1 1,44 0a22,22 0,1 1,-44 0" />
|
||||
|
||||
<!-- Play triangle (dark purple) -->
|
||||
<path
|
||||
android:fillColor="#FF231946"
|
||||
android:pathData="M47,42 L65,54 L47,66 Z" />
|
||||
|
||||
</vector>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_background" />
|
||||
<foreground android:drawable="@android:color/transparent" />
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_background" />
|
||||
<foreground android:drawable="@android:color/transparent" />
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 911 B |
|
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 553 B |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 8.9 KiB |
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 117 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 205 KiB After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 36 KiB |
@@ -46,7 +46,7 @@
|
||||
<string name="continue_watching">Continue Watching</string>
|
||||
<string name="icon_default_badge">Default</string>
|
||||
<string name="set_default_library">Set as default icon library</string>
|
||||
<string name="set_default_library_sub">Used first when changing library icons</string> <string name="app_name">My Application</string>
|
||||
<string name="set_default_library_sub">Used first when changing library icons</string> <string name="app_name">LumaPlayer</string>
|
||||
<string name="featured_title">Cold War 2</string>
|
||||
<string name="featured_subtitle">Jul 8, 2016 Crime / Mystery</string>
|
||||
<string name="library_tv_korea">TV - Korea</string>
|
||||
@@ -92,7 +92,96 @@
|
||||
<string name="icon_error_load_failed">Failed to load icons</string>
|
||||
<string name="search">Search</string>
|
||||
<string name="search_settings">Search settings</string>
|
||||
<string name="about_app_name">Luma Player</string>
|
||||
<string name="about_app_name">LumaPlayer</string>
|
||||
|
||||
<string name="empty_home_no_server">No media libraries available</string>
|
||||
<string name="empty_home_no_server_sub">Add a server in the server tab</string>
|
||||
<string name="empty_home_no_data">No media content</string>
|
||||
<string name="empty_home_no_data_sub">The current server has no content available</string>
|
||||
<string name="empty_favorites">No favorites yet</string>
|
||||
<string name="empty_favorites_sub">Browse media and add to favorites</string>
|
||||
<string name="empty_servers">No servers yet</string>
|
||||
<string name="empty_servers_sub">Tap the add button to get started</string>
|
||||
<string name="empty_calendar">No calendar data</string>
|
||||
<string name="empty_calendar_sub">Calendar feature coming soon</string>
|
||||
|
||||
<!-- Icon Library Manager -->
|
||||
<string name="icon_lib_manager_title">Icon Library Manager</string>
|
||||
<string name="icon_lib_add">Add</string>
|
||||
<string name="icon_lib_empty">No icon libraries yet</string>
|
||||
<string name="icon_lib_empty_hint">Tap top-left to add</string>
|
||||
<string name="icon_lib_not_loaded">Icons not loaded</string>
|
||||
<string name="icon_lib_no_icons">No icons</string>
|
||||
<string name="icon_lib_preview_edit">Preview · Edit</string>
|
||||
<string name="icon_lib_section_title">Icon Libraries</string>
|
||||
<string name="icon_lib_manage">Manage</string>
|
||||
<string name="icon_lib_close">Close</string>
|
||||
<string name="icon_count_suffix">%d icons</string>
|
||||
<string name="icon_count_unit">%d</string>
|
||||
|
||||
<!-- Manage Icon Library Dialog -->
|
||||
<string name="icon_lib_manage_dialog_title">Manage Icon Library</string>
|
||||
<string name="icon_lib_count">Icon Count</string>
|
||||
<string name="icon_lib_name_label">Library Name</string>
|
||||
<string name="icon_lib_url_label">Library URL (JSON)</string>
|
||||
<string name="icon_lib_preview">Icon Preview</string>
|
||||
<string name="icon_lib_refresh">Refresh Icons</string>
|
||||
<string name="icon_lib_delete">Delete</string>
|
||||
<string name="icon_lib_save">Save</string>
|
||||
|
||||
<!-- Add Icon Library Dialog -->
|
||||
<string name="icon_lib_add_title">Add Icon Library</string>
|
||||
<string name="icon_lib_name_hint">e.g. Emby Icon Library</string>
|
||||
<string name="icon_lib_fetch_preview">Fetch Preview</string>
|
||||
<string name="icon_lib_fetch_error">Fetch failed</string>
|
||||
<string name="icon_lib_preview_count">Preview (%d icons)</string>
|
||||
<string name="icon_lib_loaded_count">✓ Loaded %d icons</string>
|
||||
<string name="icon_lib_cancel">Cancel</string>
|
||||
|
||||
<!-- Icon Picker Dialog -->
|
||||
<string name="icon_picker_title">Select Icon</string>
|
||||
<string name="icon_picker_search_hint">Search icon name</string>
|
||||
<string name="icon_picker_clear_search">Clear search</string>
|
||||
<string name="icon_picker_no_lib">No icon libraries</string>
|
||||
<string name="icon_picker_no_lib_hint">Add icon libraries in the library manager first</string>
|
||||
<string name="icon_picker_loaded_hint">Loaded %d icons, tap to select</string>
|
||||
<string name="icon_picker_no_match">No matching icons found</string>
|
||||
|
||||
<!-- Server Management -->
|
||||
<string name="add_server">Add Server</string>
|
||||
<string name="edit_server">Edit Server</string>
|
||||
<string name="server_name_label">Name</string>
|
||||
<string name="server_name_placeholder">My Emby</string>
|
||||
<string name="server_url_label">URL</string>
|
||||
<string name="server_url_error">Please enter URL</string>
|
||||
<string name="server_path_label">Path</string>
|
||||
<string name="server_port_label">Port</string>
|
||||
<string name="server_port_error">Please enter port</string>
|
||||
<string name="server_username_label">Username</string>
|
||||
<string name="server_username_placeholder">Username</string>
|
||||
<string name="server_username_error">Please enter username</string>
|
||||
<string name="server_password_label">Password</string>
|
||||
<string name="server_password_placeholder">Password</string>
|
||||
<string name="server_hide_password">Hide password</string>
|
||||
<string name="server_show_password">Show password</string>
|
||||
<string name="server_note_label">Note</string>
|
||||
<string name="server_note_placeholder">Note</string>
|
||||
<string name="server_saving">Saving…</string>
|
||||
<string name="server_save">Save</string>
|
||||
<string name="server_cancel">Cancel</string>
|
||||
<string name="server_online">Online</string>
|
||||
<string name="server_offline">Offline</string>
|
||||
<string name="server_actions">Actions</string>
|
||||
<string name="server_edit">Edit</string>
|
||||
<string name="change_icon_action">Change Icon</string>
|
||||
<string name="server_just_now">Just now</string>
|
||||
<string name="view_toggle">Toggle View</string>
|
||||
<string name="server_library_manager">Icon Library</string>
|
||||
<string name="add_server_action">Add Server</string>
|
||||
<!-- Error Messages -->
|
||||
<string name="error_login_failed">Login failed</string>
|
||||
<string name="error_network">Network error: %s</string>
|
||||
<string name="error_unknown">Unknown</string>
|
||||
</resources>
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">My Application</string>
|
||||
<string name="app_name">LumaPlayer</string>
|
||||
<string name="nav_home">首页</string>
|
||||
<string name="nav_records">Vision</string>
|
||||
<string name="nav_library">服务器</string>
|
||||
@@ -92,7 +92,96 @@
|
||||
<string name="icon_error_load_failed">图标加载失败</string>
|
||||
<string name="search">搜索</string>
|
||||
<string name="search_settings">搜索设置</string>
|
||||
<string name="about_app_name">Luma Player</string>
|
||||
<string name="about_app_name">LumaPlayer</string>
|
||||
|
||||
<string name="empty_home_no_server">暂无可用的媒体库</string>
|
||||
<string name="empty_home_no_server_sub">请在资源库中添加服务器</string>
|
||||
<string name="empty_home_no_data">暂无媒体内容</string>
|
||||
<string name="empty_home_no_data_sub">当前服务器暂无可用内容</string>
|
||||
<string name="empty_favorites">暂无收藏内容</string>
|
||||
<string name="empty_favorites_sub">浏览媒体并添加收藏</string>
|
||||
<string name="empty_servers">暂无服务器</string>
|
||||
<string name="empty_servers_sub">点击右上角添加服务器</string>
|
||||
<string name="empty_calendar">暂无日历数据</string>
|
||||
<string name="empty_calendar_sub">日历功能即将推出</string>
|
||||
|
||||
<!-- Icon Library Manager -->
|
||||
<string name="icon_lib_manager_title">图标库管理</string>
|
||||
<string name="icon_lib_add">添加</string>
|
||||
<string name="icon_lib_empty">还没有图标库</string>
|
||||
<string name="icon_lib_empty_hint">点击左上角添加</string>
|
||||
<string name="icon_lib_not_loaded">图标未加载</string>
|
||||
<string name="icon_lib_no_icons">暂无图标</string>
|
||||
<string name="icon_lib_preview_edit">预览 · 修改</string>
|
||||
<string name="icon_lib_section_title">图标库</string>
|
||||
<string name="icon_lib_manage">管理</string>
|
||||
<string name="icon_lib_close">关闭</string>
|
||||
<string name="icon_count_suffix">%d 个图标</string>
|
||||
<string name="icon_count_unit">%d 个</string>
|
||||
|
||||
<!-- Manage Icon Library Dialog -->
|
||||
<string name="icon_lib_manage_dialog_title">管理图标库</string>
|
||||
<string name="icon_lib_count">图标数量</string>
|
||||
<string name="icon_lib_name_label">图标库名称</string>
|
||||
<string name="icon_lib_url_label">图标库地址 (JSON)</string>
|
||||
<string name="icon_lib_preview">图标预览</string>
|
||||
<string name="icon_lib_refresh">刷新图标</string>
|
||||
<string name="icon_lib_delete">删除</string>
|
||||
<string name="icon_lib_save">保存</string>
|
||||
|
||||
<!-- Add Icon Library Dialog -->
|
||||
<string name="icon_lib_add_title">增加图标库</string>
|
||||
<string name="icon_lib_name_hint">例如: Emby 图标库</string>
|
||||
<string name="icon_lib_fetch_preview">获取预览</string>
|
||||
<string name="icon_lib_fetch_error">获取失败</string>
|
||||
<string name="icon_lib_preview_count">预览 (%d 个图标)</string>
|
||||
<string name="icon_lib_loaded_count">✓ 已加载 %d 个图标</string>
|
||||
<string name="icon_lib_cancel">取消</string>
|
||||
|
||||
<!-- Icon Picker Dialog -->
|
||||
<string name="icon_picker_title">选择图标</string>
|
||||
<string name="icon_picker_search_hint">搜索图标名称</string>
|
||||
<string name="icon_picker_clear_search">清除搜索</string>
|
||||
<string name="icon_picker_no_lib">暂无图标库</string>
|
||||
<string name="icon_picker_no_lib_hint">请先在图标库管理中添加图标库</string>
|
||||
<string name="icon_picker_loaded_hint">已加载 %d 个图标,点击选择</string>
|
||||
<string name="icon_picker_no_match">未找到匹配的图标</string>
|
||||
|
||||
<!-- Server Management -->
|
||||
<string name="add_server">添加服务器</string>
|
||||
<string name="edit_server">编辑服务器</string>
|
||||
<string name="server_name_label">名称</string>
|
||||
<string name="server_name_placeholder">我的 Emby</string>
|
||||
<string name="server_url_label">地址</string>
|
||||
<string name="server_url_error">请输入地址</string>
|
||||
<string name="server_path_label">路径</string>
|
||||
<string name="server_port_label">端口</string>
|
||||
<string name="server_port_error">请输入端口</string>
|
||||
<string name="server_username_label">用户名</string>
|
||||
<string name="server_username_placeholder">用户名</string>
|
||||
<string name="server_username_error">请输入用户名</string>
|
||||
<string name="server_password_label">密码</string>
|
||||
<string name="server_password_placeholder">密码</string>
|
||||
<string name="server_hide_password">隐藏密码</string>
|
||||
<string name="server_show_password">显示密码</string>
|
||||
<string name="server_note_label">备注</string>
|
||||
<string name="server_note_placeholder">备注</string>
|
||||
<string name="server_saving">保存中…</string>
|
||||
<string name="server_save">保存</string>
|
||||
<string name="server_cancel">取消</string>
|
||||
<string name="server_online">在线</string>
|
||||
<string name="server_offline">离线</string>
|
||||
<string name="server_actions">操作</string>
|
||||
<string name="server_edit">编辑</string>
|
||||
<string name="change_icon_action">更换图标</string>
|
||||
<string name="server_just_now">刚刚</string>
|
||||
<string name="view_toggle">视图切换</string>
|
||||
<string name="server_library_manager">图标库管理</string>
|
||||
<string name="add_server_action">添加服务器</string>
|
||||
<!-- Error Messages -->
|
||||
<string name="error_login_failed">登录失败</string>
|
||||
<string name="error_network">网络错误: %s</string>
|
||||
<string name="error_unknown">未知</string>
|
||||
</resources>
|
||||
|
||||
|
||||
|
||||
@@ -27,5 +27,5 @@ dependencyResolutionManagement {
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.name = "EmbyPlayer"
|
||||
rootProject.name = "LumaPlayer"
|
||||
include(":app")
|
||||