better app icon
@ -101,6 +101,19 @@ compose.desktop {
|
|||||||
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
|
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
|
||||||
packageName = "net.sergeych.toread"
|
packageName = "net.sergeych.toread"
|
||||||
packageVersion = "1.0.0"
|
packageVersion = "1.0.0"
|
||||||
|
|
||||||
|
macOS {
|
||||||
|
iconFile.set(project.file("src/jvmMain/resources/icons/icon.icns"))
|
||||||
|
}
|
||||||
|
windows {
|
||||||
|
iconFile.set(project.file("src/jvmMain/resources/icons/icon.ico"))
|
||||||
|
shortcut = true
|
||||||
|
menu = true
|
||||||
|
}
|
||||||
|
linux {
|
||||||
|
iconFile.set(project.file("src/jvmMain/resources/icons/icon.png"))
|
||||||
|
shortcut = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
composeApp/src/androidMain/ic_launcher-playstore.png
Normal file
|
After Width: | Height: | Size: 82 KiB |
@ -1,65 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!--
|
|
||||||
Adaptive icon foreground: 108dp x 108dp canvas.
|
|
||||||
Safe zone: inner 72dp circle (18dp..90dp). Book (200x260) scaled 0.2769x:
|
|
||||||
translateX=26.31, translateY=18. Star sub-group at book coords (67,59) scale 0.888x.
|
|
||||||
-->
|
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="108dp"
|
|
||||||
android:height="108dp"
|
|
||||||
android:viewportWidth="108"
|
|
||||||
android:viewportHeight="108">
|
|
||||||
|
|
||||||
<group
|
|
||||||
android:translateX="26.31"
|
|
||||||
android:translateY="18"
|
|
||||||
android:scaleX="0.2769"
|
|
||||||
android:scaleY="0.2769">
|
|
||||||
|
|
||||||
<!-- Pages stack -->
|
|
||||||
<path android:fillColor="#e8e4d8"
|
|
||||||
android:pathData="M36,18 H178 V248 H36 Z"/>
|
|
||||||
<path android:fillColor="#ece9df"
|
|
||||||
android:pathData="M34,16 H176 V246 H34 Z"/>
|
|
||||||
<path android:fillColor="#f0ede3"
|
|
||||||
android:pathData="M32,14 H174 V244 H32 Z"/>
|
|
||||||
|
|
||||||
<!-- Spine -->
|
|
||||||
<path android:fillColor="#1a3d52"
|
|
||||||
android:pathData="M18,14 H36 V244 H18 Z"/>
|
|
||||||
<path android:fillColor="#00000000"
|
|
||||||
android:strokeColor="#30000000"
|
|
||||||
android:strokeWidth="1"
|
|
||||||
android:pathData="M35,14 V244"/>
|
|
||||||
|
|
||||||
<!-- Cover -->
|
|
||||||
<path android:fillColor="#2c5f7a"
|
|
||||||
android:pathData="M32,14 H174 V244 H32 Z"/>
|
|
||||||
|
|
||||||
<!-- Cover border -->
|
|
||||||
<path android:fillColor="#00000000"
|
|
||||||
android:strokeColor="#30ffffff"
|
|
||||||
android:strokeWidth="1.5"
|
|
||||||
android:pathData="M40,22 H166 V236 H40 Z"/>
|
|
||||||
|
|
||||||
<!-- Star arms -->
|
|
||||||
<group
|
|
||||||
android:translateX="67"
|
|
||||||
android:translateY="59"
|
|
||||||
android:scaleX="0.888"
|
|
||||||
android:scaleY="0.888">
|
|
||||||
<path android:fillColor="#6197b4"
|
|
||||||
android:pathData="m 32.120065,25.957965 -15.0296,-9.2912 c -0.3066,-0.187 -0.6532,0.1603 -0.4666,0.4676 l 8.9112,14.4745 c 0.2399,0.3874 0.5665,0.7013 0.9597,0.9284 l 14.0032,8.0555 V 0.34209525 c 0,-0.394094 -0.5532,-0.474248 -0.6665,-0.1002 z"/>
|
|
||||||
<path android:fillColor="#bdccd6"
|
|
||||||
android:pathData="m 25.901665,48.988865 -9.271,15.0556 c -0.1866,0.3073 0.16,0.6546 0.4665,0.4676 l 14.4431,-8.9305 c 0.3866,-0.2405 0.6999,-0.5678 0.9265,-0.9619 l 8.038,-14.0336 H 0.34134532 c -0.393231,0 -0.473212,0.5544 -0.09997,0.6679 z"/>
|
|
||||||
<path android:fillColor="#94bfcf"
|
|
||||||
android:pathData="m 55.101065,32.189965 9.2711,-15.0623 c 0.1866,-0.3072 -0.16,-0.6546 -0.4666,-0.4675 l -14.4431,8.9371 c -0.3865,0.2405 -0.6998,0.5678 -0.9264,0.9619 l -8.038,14.027 h 40.1634 c 0.3932,0 0.4732,-0.5544 0.1,-0.668 z"/>
|
|
||||||
<path android:fillColor="#eee9d9"
|
|
||||||
android:pathData="m 54.507965,48.641565 -14.0099,-8.0555 v 40.2507 c 0,0.3941 0.5532,0.4742 0.6665,0.1002 l 7.7181,-25.7094 15.0296,9.2912 c 0.3066,0.187 0.6532,-0.1603 0.4665,-0.4676 l -8.9177,-14.4812 c -0.2333,-0.3807 -0.5666,-0.7013 -0.9531,-0.9284 z"/>
|
|
||||||
</group>
|
|
||||||
|
|
||||||
<!-- Bottom spine accent -->
|
|
||||||
<path android:fillColor="#0e2030"
|
|
||||||
android:pathData="M18,228 H36 V244 H18 Z"/>
|
|
||||||
</group>
|
|
||||||
</vector>
|
|
||||||
@ -0,0 +1,120 @@
|
|||||||
|
<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="512"
|
||||||
|
android:viewportHeight="512">
|
||||||
|
<group android:scaleX="0.84"
|
||||||
|
android:scaleY="0.84"
|
||||||
|
android:translateX="40.96"
|
||||||
|
android:translateY="40.96">
|
||||||
|
<path
|
||||||
|
android:pathData="M0,0h512v512h-512z">
|
||||||
|
<aapt:attr name="android:fillColor">
|
||||||
|
<gradient
|
||||||
|
android:centerX="230.4"
|
||||||
|
android:centerY="179.2"
|
||||||
|
android:gradientRadius="384"
|
||||||
|
android:type="radial">
|
||||||
|
<item android:offset="0" android:color="#FF2E6B8A"/>
|
||||||
|
<item android:offset="1" android:color="#FF0D2535"/>
|
||||||
|
</gradient>
|
||||||
|
</aapt:attr>
|
||||||
|
</path>
|
||||||
|
<path
|
||||||
|
android:pathData="M116.79,259.93a145.45,160 0,1 0,290.9 0a145.45,160 0,1 0,-290.9 0z"
|
||||||
|
android:strokeAlpha="0.25"
|
||||||
|
android:strokeWidth="0.727253"
|
||||||
|
android:fillColor="#2e6b8a"
|
||||||
|
android:fillAlpha="0.25"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M156.06,140.66L372.78,140.66A7.27,7.27 0,0 1,380.05 147.93L380.05,364.65A7.27,7.27 0,0 1,372.78 371.92L156.06,371.92A7.27,7.27 0,0 1,148.79 364.65L148.79,147.93A7.27,7.27 0,0 1,156.06 140.66z">
|
||||||
|
<aapt:attr name="android:fillColor">
|
||||||
|
<gradient
|
||||||
|
android:startX="148.79"
|
||||||
|
android:startY="140.66"
|
||||||
|
android:endX="380.05"
|
||||||
|
android:endY="140.66"
|
||||||
|
android:type="linear">
|
||||||
|
<item android:offset="0" android:color="#FFF0EDE3"/>
|
||||||
|
<item android:offset="1" android:color="#FFE8E4D8"/>
|
||||||
|
</gradient>
|
||||||
|
</aapt:attr>
|
||||||
|
</path>
|
||||||
|
<path
|
||||||
|
android:pathData="M150.24,134.84L366.96,134.84A7.27,7.27 0,0 1,374.24 142.11L374.24,358.83A7.27,7.27 0,0 1,366.96 366.1L150.24,366.1A7.27,7.27 0,0 1,142.97 358.83L142.97,142.11A7.27,7.27 0,0 1,150.24 134.84z"
|
||||||
|
android:fillColor="#ece9df"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M144.42,129.02L361.15,129.02A7.27,7.27 0,0 1,368.42 136.29L368.42,353.01A7.27,7.27 0,0 1,361.15 360.29L144.42,360.29A7.27,7.27 0,0 1,137.15 353.01L137.15,136.29A7.27,7.27 0,0 1,144.42 129.02z"
|
||||||
|
android:fillColor="#f0ede3"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M129,128.77L155.69,128.77A7.85,7.85 0,0 1,163.53 136.61L163.53,382.98A7.85,7.85 0,0 1,155.69 390.83L129,390.83A7.85,7.85 0,0 1,121.15 382.98L121.15,136.61A7.85,7.85 0,0 1,129 128.77z"
|
||||||
|
android:strokeWidth="0.755863"
|
||||||
|
android:strokeColor="#00000000">
|
||||||
|
<aapt:attr name="android:fillColor">
|
||||||
|
<gradient
|
||||||
|
android:startX="121.15"
|
||||||
|
android:startY="128.77"
|
||||||
|
android:endX="163.53"
|
||||||
|
android:endY="128.77"
|
||||||
|
android:type="linear">
|
||||||
|
<item android:offset="0" android:color="#FF122C3C"/>
|
||||||
|
<item android:offset="1" android:color="#FF2E6B8A"/>
|
||||||
|
</gradient>
|
||||||
|
</aapt:attr>
|
||||||
|
</path>
|
||||||
|
<path
|
||||||
|
android:pathData="M158.97,129.02L380.05,129.02A7.27,7.27 0,0 1,387.33 136.29L387.33,383.56A7.27,7.27 0,0 1,380.05 390.83L158.97,390.83A7.27,7.27 0,0 1,151.7 383.56L151.7,136.29A7.27,7.27 0,0 1,158.97 129.02z"
|
||||||
|
android:strokeWidth="0.727253">
|
||||||
|
<aapt:attr name="android:fillColor">
|
||||||
|
<gradient
|
||||||
|
android:startX="151.7"
|
||||||
|
android:startY="129.02"
|
||||||
|
android:endX="387.33"
|
||||||
|
android:endY="390.83"
|
||||||
|
android:type="linear">
|
||||||
|
<item android:offset="0" android:color="#FF3A82A6"/>
|
||||||
|
<item android:offset="1" android:color="#FF1A3D52"/>
|
||||||
|
</gradient>
|
||||||
|
</aapt:attr>
|
||||||
|
</path>
|
||||||
|
<path
|
||||||
|
android:pathData="M158.97,129.02L380.05,129.02A7.27,7.27 0,0 1,387.33 136.29L387.33,383.56A7.27,7.27 0,0 1,380.05 390.83L158.97,390.83A7.27,7.27 0,0 1,151.7 383.56L151.7,136.29A7.27,7.27 0,0 1,158.97 129.02z"
|
||||||
|
android:strokeWidth="0.727253">
|
||||||
|
<aapt:attr name="android:fillColor">
|
||||||
|
<gradient
|
||||||
|
android:startX="151.7"
|
||||||
|
android:startY="129.02"
|
||||||
|
android:endX="222.39"
|
||||||
|
android:endY="390.83"
|
||||||
|
android:type="linear">
|
||||||
|
<item android:offset="0" android:color="#2DFFFFFF"/>
|
||||||
|
<item android:offset="1" android:color="#00FFFFFF"/>
|
||||||
|
</gradient>
|
||||||
|
</aapt:attr>
|
||||||
|
</path>
|
||||||
|
<path
|
||||||
|
android:pathData="M160.42,136.29L160.42,383.56"
|
||||||
|
android:strokeWidth="1.45451"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#30000000"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M166.93,141.3L373.24,141.3A4.69,4.69 0,0 1,377.93 145.99L377.93,377.33A4.69,4.69 0,0 1,373.24 382.01L166.93,382.01A4.69,4.69 0,0 1,162.24 377.33L162.24,145.99A4.69,4.69 0,0 1,166.93 141.3z"
|
||||||
|
android:strokeAlpha="0.104098"
|
||||||
|
android:strokeWidth="3.10595"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#000000"/>
|
||||||
|
<path
|
||||||
|
android:pathData="m249.01,223.24 l-37.71,-23.31c-0.77,-0.47 -1.64,0.4 -1.17,1.17l22.36,36.32c0.6,0.97 1.42,1.76 2.41,2.33l35.13,20.21L270.03,158.97c0,-0.99 -1.39,-1.19 -1.67,-0.25z"
|
||||||
|
android:fillColor="#6197b4"/>
|
||||||
|
<path
|
||||||
|
android:pathData="m233.41,281.02 l-23.26,37.77c-0.47,0.77 0.4,1.64 1.17,1.17l36.24,-22.41c0.97,-0.6 1.76,-1.42 2.32,-2.41l20.17,-35.21L169.28,259.94c-0.99,0 -1.19,1.39 -0.25,1.68z"
|
||||||
|
android:fillColor="#bdccd6"/>
|
||||||
|
<path
|
||||||
|
android:pathData="m306.67,238.88 l23.26,-37.79c0.47,-0.77 -0.4,-1.64 -1.17,-1.17l-36.24,22.42c-0.97,0.6 -1.76,1.42 -2.32,2.41l-20.17,35.19l100.77,0c0.99,0 1.19,-1.39 0.25,-1.68z"
|
||||||
|
android:fillColor="#94bfcf"/>
|
||||||
|
<path
|
||||||
|
android:pathData="m305.19,280.15 l-35.15,-20.21l0,100.99c0,0.99 1.39,1.19 1.67,0.25l19.36,-64.51 37.71,23.31c0.77,0.47 1.64,-0.4 1.17,-1.17l-22.37,-36.33c-0.59,-0.96 -1.42,-1.76 -2.39,-2.33z"
|
||||||
|
android:fillColor="#eee9d9"/>
|
||||||
|
</group>
|
||||||
|
</vector>
|
||||||
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@drawable/ic_launcher_background"/>
|
<background android:drawable="@mipmap/ic_launcher_background"/>
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||||
</adaptive-icon>
|
</adaptive-icon>
|
||||||
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@drawable/ic_launcher_background"/>
|
<background android:drawable="@mipmap/ic_launcher_background"/>
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||||
</adaptive-icon>
|
</adaptive-icon>
|
||||||
|
Before Width: | Height: | Size: 6.0 KiB |
BIN
composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 40 B |
|
Before Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
BIN
composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 40 B |
|
Before Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 9.9 KiB |
BIN
composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 42 B |
|
Before Width: | Height: | Size: 9.9 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 20 KiB |
BIN
composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
|
After Width: | Height: | Size: 48 B |
|
Before Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 35 KiB |
BIN
composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 48 B |
|
Before Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 15 KiB |
@ -30,6 +30,7 @@ import kotlinx.coroutines.launch
|
|||||||
|
|
||||||
private const val DefaultToastDurationMillis = 1_600L
|
private const val DefaultToastDurationMillis = 1_600L
|
||||||
private const val DeleteUndoDurationMillis = 5_000L
|
private const val DeleteUndoDurationMillis = 5_000L
|
||||||
|
private const val BackgroundLibraryPageSize = 50
|
||||||
|
|
||||||
private data class AppToastData(
|
private data class AppToastData(
|
||||||
val id: Long,
|
val id: Long,
|
||||||
@ -151,7 +152,7 @@ private fun BookReaderApp(
|
|||||||
durationMillis: Long,
|
durationMillis: Long,
|
||||||
) -> Unit,
|
) -> Unit,
|
||||||
) {
|
) {
|
||||||
var state by remember { mutableStateOf<AppState>(AppState.LoadingLibrary) }
|
var state by remember { mutableStateOf<AppState>(AppState.LoadingStartup) }
|
||||||
var activeScan by remember { mutableStateOf<LibraryScanProgress?>(null) }
|
var activeScan by remember { mutableStateOf<LibraryScanProgress?>(null) }
|
||||||
var scanJob by remember { mutableStateOf<Job?>(null) }
|
var scanJob by remember { mutableStateOf<Job?>(null) }
|
||||||
var pendingDelete by remember { mutableStateOf<PendingLibraryDelete?>(null) }
|
var pendingDelete by remember { mutableStateOf<PendingLibraryDelete?>(null) }
|
||||||
@ -165,6 +166,34 @@ private fun BookReaderApp(
|
|||||||
state = loadStartupState()
|
state = loadStartupState()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val activeBookState = when (val current = state) {
|
||||||
|
is AppState.Reader -> current.fileId to current.libraryItems.isEmpty()
|
||||||
|
is AppState.BookInfo -> current.fileId to current.libraryItems.isEmpty()
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
LaunchedEffect(activeBookState?.first, activeBookState?.second) {
|
||||||
|
val (fileId, needsLibraryItems) = activeBookState ?: return@LaunchedEffect
|
||||||
|
if (!needsLibraryItems) return@LaunchedEffect
|
||||||
|
runCatching { loadLibraryItemsPage(BackgroundLibraryPageSize, 0) }
|
||||||
|
.onSuccess { items ->
|
||||||
|
state = when (val current = state) {
|
||||||
|
is AppState.Reader ->
|
||||||
|
if (current.fileId == fileId && current.libraryItems.isEmpty()) {
|
||||||
|
current.copy(libraryItems = items)
|
||||||
|
} else {
|
||||||
|
current
|
||||||
|
}
|
||||||
|
is AppState.BookInfo ->
|
||||||
|
if (current.fileId == fileId && current.libraryItems.isEmpty()) {
|
||||||
|
current.copy(libraryItems = items)
|
||||||
|
} else {
|
||||||
|
current
|
||||||
|
}
|
||||||
|
else -> current
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun commitPendingDelete(delete: PendingLibraryDelete) {
|
fun commitPendingDelete(delete: PendingLibraryDelete) {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
val result = deleteLibraryBook(delete.request.fileId, delete.request.title)
|
val result = deleteLibraryBook(delete.request.fileId, delete.request.title)
|
||||||
@ -238,18 +267,18 @@ private fun BookReaderApp(
|
|||||||
)
|
)
|
||||||
is AppState.Reader -> {
|
is AppState.Reader -> {
|
||||||
scope.launch { saveActiveReadingFileId(null) }
|
scope.launch { saveActiveReadingFileId(null) }
|
||||||
AppState.Library(emptyList(), current.scanPath, current.message)
|
AppState.Library(current.libraryItems, current.scanPath, current.message)
|
||||||
}
|
}
|
||||||
is AppState.Scan -> AppState.Library(current.items, current.scanPath, current.message)
|
is AppState.Scan -> AppState.Library(current.items, current.scanPath, current.message)
|
||||||
is AppState.Error -> AppState.LoadingLibrary
|
is AppState.Error -> AppState.LoadingStartup
|
||||||
is AppState.Library, AppState.LoadingLibrary -> current
|
is AppState.Library, AppState.LoadingStartup -> current
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val navigationDepth = when (state) {
|
val navigationDepth = when (state) {
|
||||||
is AppState.BookInfo -> 2
|
is AppState.BookInfo -> 2
|
||||||
is AppState.Error, is AppState.Reader, is AppState.Scan -> 1
|
is AppState.Error, is AppState.Reader, is AppState.Scan -> 1
|
||||||
is AppState.Library, AppState.LoadingLibrary -> 0
|
is AppState.Library, AppState.LoadingStartup -> 0
|
||||||
} + if (imageViewer != null) 1 else 0
|
} + if (imageViewer != null) 1 else 0
|
||||||
|
|
||||||
PlatformBackHandler(
|
PlatformBackHandler(
|
||||||
@ -291,7 +320,7 @@ private fun BookReaderApp(
|
|||||||
} else {
|
} else {
|
||||||
AppState.Library(current.items, path, message)
|
AppState.Library(current.items, path, message)
|
||||||
}
|
}
|
||||||
AppState.LoadingLibrary -> loadLibraryState(message, path)
|
AppState.LoadingStartup -> loadLibraryState(message, path)
|
||||||
is AppState.Reader -> current.copy(message = message)
|
is AppState.Reader -> current.copy(message = message)
|
||||||
is AppState.BookInfo -> current.copy(message = message)
|
is AppState.BookInfo -> current.copy(message = message)
|
||||||
is AppState.Error -> current
|
is AppState.Error -> current
|
||||||
@ -300,7 +329,7 @@ private fun BookReaderApp(
|
|||||||
}
|
}
|
||||||
|
|
||||||
when (val current = state) {
|
when (val current = state) {
|
||||||
AppState.LoadingLibrary -> LoadingScreen("Opening library")
|
AppState.LoadingStartup -> LoadingScreen("Opening book")
|
||||||
is AppState.Library -> LibraryScreen(
|
is AppState.Library -> LibraryScreen(
|
||||||
state = current,
|
state = current,
|
||||||
activeScan = activeScan,
|
activeScan = activeScan,
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import net.sergeych.toread.fb2.Fb2Book
|
|||||||
import net.sergeych.toread.fb2.Fb2Format
|
import net.sergeych.toread.fb2.Fb2Format
|
||||||
|
|
||||||
internal sealed interface AppState {
|
internal sealed interface AppState {
|
||||||
data object LoadingLibrary : AppState
|
data object LoadingStartup : AppState
|
||||||
data class Library(
|
data class Library(
|
||||||
val items: List<LibraryItem>,
|
val items: List<LibraryItem>,
|
||||||
val scanPath: String,
|
val scanPath: String,
|
||||||
@ -37,39 +37,40 @@ internal sealed interface AppState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal suspend fun loadStartupState(): AppState {
|
internal suspend fun loadStartupState(): AppState {
|
||||||
val library = loadLibraryState()
|
val scanPath = try {
|
||||||
if (library !is AppState.Library) return library
|
defaultLibraryScanPath().orEmpty()
|
||||||
|
} catch (t: Throwable) {
|
||||||
|
return AppState.Error(t.message ?: "Could not open library.")
|
||||||
|
}
|
||||||
loadPlatformOpenBookRequest()?.let { request ->
|
loadPlatformOpenBookRequest()?.let { request ->
|
||||||
return runCatching {
|
return runCatching {
|
||||||
AppState.Reader(
|
AppState.Reader(
|
||||||
fileId = request.id,
|
fileId = request.id,
|
||||||
book = Fb2Format.parse(request.bytes, request.displayName),
|
book = Fb2Format.parse(request.bytes, request.displayName),
|
||||||
libraryItems = library.items,
|
libraryItems = emptyList(),
|
||||||
scanPath = library.scanPath,
|
scanPath = scanPath,
|
||||||
message = library.message,
|
|
||||||
)
|
)
|
||||||
}.getOrElse {
|
}.getOrElse {
|
||||||
AppState.Library(library.items, library.scanPath, it.message ?: "Could not open ${request.displayName}.")
|
AppState.Library(emptyList(), scanPath, it.message ?: "Could not open ${request.displayName}.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val activeFileId = loadActiveReadingFileId() ?: return library
|
val activeFileId = loadActiveReadingFileId() ?: return AppState.Library(emptyList(), scanPath)
|
||||||
val item = loadLibraryItem(activeFileId)
|
val item = loadLibraryItem(activeFileId)
|
||||||
if (item == null) {
|
if (item == null) {
|
||||||
saveActiveReadingFileId(null)
|
saveActiveReadingFileId(null)
|
||||||
return library
|
return AppState.Library(emptyList(), scanPath)
|
||||||
}
|
}
|
||||||
return runCatching {
|
return runCatching {
|
||||||
val bytes = openLibraryBook(activeFileId) ?: error("Book file is not available.")
|
val bytes = openLibraryBook(activeFileId) ?: error("Book file is not available.")
|
||||||
AppState.Reader(
|
AppState.Reader(
|
||||||
fileId = activeFileId,
|
fileId = activeFileId,
|
||||||
book = Fb2Format.parse(bytes, item.storageUri ?: item.title),
|
book = Fb2Format.parse(bytes, item.storageUri ?: item.title),
|
||||||
libraryItems = library.items,
|
libraryItems = emptyList(),
|
||||||
scanPath = library.scanPath,
|
scanPath = scanPath,
|
||||||
message = library.message,
|
|
||||||
)
|
)
|
||||||
}.getOrElse {
|
}.getOrElse {
|
||||||
saveActiveReadingFileId(null)
|
saveActiveReadingFileId(null)
|
||||||
AppState.Library(library.items, library.scanPath, it.message ?: "Could not reopen last book.")
|
AppState.Library(emptyList(), scanPath, it.message ?: "Could not reopen last book.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
BIN
composeApp/src/jvmMain/resources/icons/icon.icns
Normal file
BIN
composeApp/src/jvmMain/resources/icons/icon.ico
Normal file
|
After Width: | Height: | Size: 134 KiB |
BIN
composeApp/src/jvmMain/resources/icons/icon.png
Normal file
|
After Width: | Height: | Size: 212 KiB |
59
image_src/icon-app-large.svg
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- 512x512 app icon - square book mark for launcher use -->
|
||||||
|
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<radialGradient id="bgGrad" cx="45%" cy="35%" r="75%">
|
||||||
|
<stop offset="0%" stop-color="#2e6b8a"/>
|
||||||
|
<stop offset="100%" stop-color="#0d2535"/>
|
||||||
|
</radialGradient>
|
||||||
|
<filter id="shadow" x="-10%" y="-5%" width="130%" height="120%">
|
||||||
|
<feOffset in="SourceAlpha" dx="5" dy="7" result="offset"/>
|
||||||
|
<feGaussianBlur in="offset" stdDeviation="8" result="blur"/>
|
||||||
|
<feColorMatrix in="blur" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.4 0" result="shadowBlur"/>
|
||||||
|
<feMerge>
|
||||||
|
<feMergeNode in="shadowBlur"/>
|
||||||
|
<feMergeNode in="SourceGraphic"/>
|
||||||
|
</feMerge>
|
||||||
|
</filter>
|
||||||
|
<linearGradient id="pageGrad" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||||
|
<stop offset="0%" stop-color="#f0ede3"/>
|
||||||
|
<stop offset="100%" stop-color="#e8e4d8"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="coverGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#3a82a6"/>
|
||||||
|
<stop offset="100%" stop-color="#1a3d52"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="spineGrad" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||||
|
<stop offset="0%" stop-color="#122c3c"/>
|
||||||
|
<stop offset="100%" stop-color="#2e6b8a"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="coverShine" x1="0%" y1="0%" x2="30%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#ffffff" stop-opacity="0.18"/>
|
||||||
|
<stop offset="100%" stop-color="#ffffff" stop-opacity="0"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<rect width="512" height="512" fill="url(#bgGrad)"/>
|
||||||
|
<ellipse cx="268" cy="256" rx="200" ry="220" fill="#2e6b8a" opacity="0.25"/>
|
||||||
|
|
||||||
|
<g filter="url(#shadow)">
|
||||||
|
<rect x="112" y="92" width="318" height="318" rx="10" fill="url(#pageGrad)"/>
|
||||||
|
<rect x="104" y="84" width="318" height="318" rx="10" fill="#ece9df"/>
|
||||||
|
<rect x="96" y="76" width="318" height="318" rx="10" fill="#f0ede3"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<rect x="74" y="76" width="54" height="360" rx="10" fill="url(#spineGrad)"/>
|
||||||
|
<rect x="116" y="76" width="324" height="360" rx="10" fill="url(#coverGrad)"/>
|
||||||
|
<rect x="116" y="76" width="324" height="360" rx="10" fill="url(#coverShine)"/>
|
||||||
|
<line x1="128" y1="86" x2="128" y2="426" stroke="#00000030" stroke-width="2"/>
|
||||||
|
<rect x="140" y="100" width="276" height="312" rx="6" fill="none" stroke="#ffffff30" stroke-width="4"/>
|
||||||
|
|
||||||
|
<g transform="translate(139, 116) scale(3.45)">
|
||||||
|
<path d="m 32.120065,25.957965 -15.0296,-9.2912 c -0.3066,-0.187 -0.6532,0.1603 -0.4666,0.4676 l 8.9112,14.4745 c 0.2399,0.3874 0.5665,0.7013 0.9597,0.9284 l 14.0032,8.0555 V 0.34209525 c 0,-0.394094 -0.5532,-0.474248 -0.6665,-0.1002 z" fill="#6197b4"/>
|
||||||
|
<path d="m 25.901665,48.988865 -9.271,15.0556 c -0.1866,0.3073 0.16,0.6546 0.4665,0.4676 l 14.4431,-8.9305 c 0.3866,-0.2405 0.6999,-0.5678 0.9265,-0.9619 l 8.038,-14.0336 H 0.34134532 c -0.393231,0 -0.473212,0.5544 -0.09997,0.6679 z" fill="#bdccd6"/>
|
||||||
|
<path d="m 55.101065,32.189965 9.2711,-15.0623 c 0.1866,-0.3072 -0.16,-0.6546 -0.4666,-0.4675 l -14.4431,8.9371 c -0.3865,0.2405 -0.6998,0.5678 -0.9264,0.9619 l -8.038,14.027 h 40.1634 c 0.3932,0 0.4732,-0.5544 0.1,-0.668 z" fill="#94bfcf"/>
|
||||||
|
<path d="m 54.507965,48.641565 -14.0099,-8.0555 v 40.2507 c 0,0.3941 0.5532,0.4742 0.6665,0.1002 l 7.7181,-25.7094 15.0296,9.2912 c 0.3066,0.187 0.6532,-0.1603 0.4665,-0.4676 l -8.9177,-14.4812 c -0.2333,-0.3807 -0.5666,-0.7013 -0.9531,-0.9284 z" fill="#eee9d9"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<rect x="74" y="390" width="54" height="46" rx="0 0 10 10" fill="#0e2030" opacity="0.75"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.6 KiB |
@ -1,65 +1,264 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<!-- 512x512 app icon — desktop launcher & Android (keep content in inner ~340px safe zone) -->
|
<!-- 512x512 app icon - square book mark for launcher use -->
|
||||||
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
<svg
|
||||||
<radialGradient id="bgGrad" cx="45%" cy="35%" r="75%">
|
width="512"
|
||||||
<stop offset="0%" stop-color="#2e6b8a"/>
|
height="512"
|
||||||
<stop offset="100%" stop-color="#0d2535"/>
|
viewBox="0 0 512 512"
|
||||||
|
fill="none"
|
||||||
|
version="1.1"
|
||||||
|
id="svg20"
|
||||||
|
sodipodi:docname="icon-app.svg"
|
||||||
|
inkscape:version="1.4.4 (1:1.4.4+202605061436+dcaf3e7d9e)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview20"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:zoom="1.7832031"
|
||||||
|
inkscape:cx="264.13144"
|
||||||
|
inkscape:cy="289.36693"
|
||||||
|
inkscape:window-width="1861"
|
||||||
|
inkscape:window-height="1163"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg20" />
|
||||||
|
<defs
|
||||||
|
id="defs10">
|
||||||
|
<radialGradient
|
||||||
|
id="bgGrad"
|
||||||
|
cx="45%"
|
||||||
|
cy="35%"
|
||||||
|
r="75%">
|
||||||
|
<stop
|
||||||
|
offset="0%"
|
||||||
|
stop-color="#2e6b8a"
|
||||||
|
id="stop1" />
|
||||||
|
<stop
|
||||||
|
offset="100%"
|
||||||
|
stop-color="#0d2535"
|
||||||
|
id="stop2" />
|
||||||
</radialGradient>
|
</radialGradient>
|
||||||
<filter id="shadow" x="-10%" y="-5%" width="130%" height="120%">
|
<filter
|
||||||
<feDropShadow dx="5" dy="7" stdDeviation="8" flood-color="#00000066"/>
|
id="shadow"
|
||||||
|
x="-0.05748503"
|
||||||
|
y="-0.05748503"
|
||||||
|
width="1.1299401"
|
||||||
|
height="1.1359281">
|
||||||
|
<feOffset
|
||||||
|
in="SourceAlpha"
|
||||||
|
dx="5"
|
||||||
|
dy="7"
|
||||||
|
result="offset"
|
||||||
|
id="feOffset2" />
|
||||||
|
<feGaussianBlur
|
||||||
|
in="offset"
|
||||||
|
stdDeviation="8"
|
||||||
|
result="blur"
|
||||||
|
id="feGaussianBlur2" />
|
||||||
|
<feColorMatrix
|
||||||
|
in="blur"
|
||||||
|
type="matrix"
|
||||||
|
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.4 0"
|
||||||
|
result="shadowBlur"
|
||||||
|
id="feColorMatrix2" />
|
||||||
|
<feMerge
|
||||||
|
id="feMerge3">
|
||||||
|
<feMergeNode
|
||||||
|
in="shadowBlur"
|
||||||
|
id="feMergeNode2" />
|
||||||
|
<feMergeNode
|
||||||
|
in="SourceGraphic"
|
||||||
|
id="feMergeNode3" />
|
||||||
|
</feMerge>
|
||||||
</filter>
|
</filter>
|
||||||
<linearGradient id="pageGrad" x1="0%" y1="0%" x2="100%" y2="0%">
|
<linearGradient
|
||||||
<stop offset="0%" stop-color="#f0ede3"/>
|
id="pageGrad"
|
||||||
<stop offset="100%" stop-color="#e8e4d8"/>
|
x1="112"
|
||||||
|
y1="92"
|
||||||
|
x2="430"
|
||||||
|
y2="92"
|
||||||
|
gradientUnits="userSpaceOnUse">
|
||||||
|
<stop
|
||||||
|
offset="0%"
|
||||||
|
stop-color="#f0ede3"
|
||||||
|
id="stop3" />
|
||||||
|
<stop
|
||||||
|
offset="100%"
|
||||||
|
stop-color="#e8e4d8"
|
||||||
|
id="stop4" />
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
<linearGradient id="coverGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
<linearGradient
|
||||||
<stop offset="0%" stop-color="#3a82a6"/>
|
id="coverGrad"
|
||||||
<stop offset="100%" stop-color="#1a3d52"/>
|
x1="122.27474"
|
||||||
|
y1="72.099931"
|
||||||
|
x2="463.80072"
|
||||||
|
y2="413.62592"
|
||||||
|
gradientTransform="matrix(0.6899326,0,0,0.76659181,67.335419,73.748798)"
|
||||||
|
gradientUnits="userSpaceOnUse">
|
||||||
|
<stop
|
||||||
|
offset="0%"
|
||||||
|
stop-color="#3a82a6"
|
||||||
|
id="stop5" />
|
||||||
|
<stop
|
||||||
|
offset="100%"
|
||||||
|
stop-color="#1a3d52"
|
||||||
|
id="stop6" />
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
<linearGradient id="spineGrad" x1="0%" y1="0%" x2="100%" y2="0%">
|
<linearGradient
|
||||||
<stop offset="0%" stop-color="#122c3c"/>
|
id="spineGrad"
|
||||||
<stop offset="100%" stop-color="#2e6b8a"/>
|
x1="191.06718"
|
||||||
|
y1="29.434673"
|
||||||
|
x2="330.49458"
|
||||||
|
y2="29.434673"
|
||||||
|
gradientTransform="matrix(0.30396746,0,0,1.8795869,63.07392,73.440088)"
|
||||||
|
gradientUnits="userSpaceOnUse">
|
||||||
|
<stop
|
||||||
|
offset="0%"
|
||||||
|
stop-color="#122c3c"
|
||||||
|
id="stop7" />
|
||||||
|
<stop
|
||||||
|
offset="100%"
|
||||||
|
stop-color="#2e6b8a"
|
||||||
|
id="stop8" />
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
<linearGradient id="coverShine" x1="0%" y1="0%" x2="30%" y2="100%">
|
<linearGradient
|
||||||
<stop offset="0%" stop-color="#ffffff" stop-opacity="0.18"/>
|
id="coverShine"
|
||||||
<stop offset="100%" stop-color="#ffffff" stop-opacity="0"/>
|
x1="122.27474"
|
||||||
|
y1="72.099931"
|
||||||
|
x2="224.73254"
|
||||||
|
y2="413.62592"
|
||||||
|
gradientTransform="matrix(0.6899326,0,0,0.76659181,67.335419,73.748798)"
|
||||||
|
gradientUnits="userSpaceOnUse">
|
||||||
|
<stop
|
||||||
|
offset="0%"
|
||||||
|
stop-color="#ffffff"
|
||||||
|
stop-opacity="0.18"
|
||||||
|
id="stop9" />
|
||||||
|
<stop
|
||||||
|
offset="100%"
|
||||||
|
stop-color="#ffffff"
|
||||||
|
stop-opacity="0"
|
||||||
|
id="stop10" />
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
</defs>
|
</defs>
|
||||||
|
<rect
|
||||||
<!-- Full-bleed background -->
|
width="512"
|
||||||
<rect width="512" height="512" fill="url(#bgGrad)"/>
|
height="512"
|
||||||
|
fill="url(#bgGrad)"
|
||||||
<!-- Subtle radial glow behind book -->
|
id="rect10" />
|
||||||
<ellipse cx="268" cy="256" rx="200" ry="220" fill="#2e6b8a" opacity="0.25"/>
|
<ellipse
|
||||||
|
cx="262.23917"
|
||||||
<!-- Book, scaled 1.84x and centered (book canvas 200x260 → 368x478, centered in 512x512) -->
|
cy="259.92554"
|
||||||
<!-- x_offset=(512-368)/2=72, y_offset=(512-478)/2=17 -->
|
rx="145.45056"
|
||||||
<g transform="translate(72, 17) scale(1.84)">
|
ry="159.99562"
|
||||||
<!-- Pages -->
|
fill="#2e6b8a"
|
||||||
<rect x="36" y="18" width="142" height="230" rx="2" fill="url(#pageGrad)" filter="url(#shadow)"/>
|
opacity="0.25"
|
||||||
<rect x="34" y="16" width="142" height="230" rx="2" fill="#ece9df"/>
|
id="ellipse10"
|
||||||
<rect x="32" y="14" width="142" height="230" rx="2" fill="#f0ede3"/>
|
style="stroke-width:0.727253" />
|
||||||
<!-- Spine -->
|
<g
|
||||||
<rect x="18" y="14" width="18" height="230" rx="2" fill="url(#spineGrad)"/>
|
filter="url(#shadow)"
|
||||||
<line x1="35" y1="14" x2="35" y2="244" stroke="#00000030" stroke-width="1"/>
|
id="g13"
|
||||||
<!-- Cover -->
|
transform="matrix(0.72725281,0,0,0.72725281,67.335419,73.748798)">
|
||||||
<rect x="32" y="14" width="142" height="230" rx="2" fill="url(#coverGrad)"/>
|
<rect
|
||||||
<rect x="32" y="14" width="142" height="230" rx="2" fill="url(#coverShine)"/>
|
x="112"
|
||||||
<!-- Cover border -->
|
y="92"
|
||||||
<rect x="40" y="22" width="126" height="214" rx="1" fill="none" stroke="#ffffff30" stroke-width="1.5"/>
|
width="318"
|
||||||
<!-- Star (scale 0.888 within book, translate 67,59) -->
|
height="318"
|
||||||
<g transform="translate(67, 59) scale(0.888)">
|
rx="10"
|
||||||
<path d="m 32.120065,25.957965 -15.0296,-9.2912 c -0.3066,-0.187 -0.6532,0.1603 -0.4666,0.4676 l 8.9112,14.4745 c 0.2399,0.3874 0.5665,0.7013 0.9597,0.9284 l 14.0032,8.0555 V 0.34209525 c 0,-0.394094 -0.5532,-0.474248 -0.6665,-0.1002 z" fill="#6197b4"/>
|
fill="url(#pageGrad)"
|
||||||
<path d="m 25.901665,48.988865 -9.271,15.0556 c -0.1866,0.3073 0.16,0.6546 0.4665,0.4676 l 14.4431,-8.9305 c 0.3866,-0.2405 0.6999,-0.5678 0.9265,-0.9619 l 8.038,-14.0336 H 0.34134532 c -0.393231,0 -0.473212,0.5544 -0.09997,0.6679 z" fill="#bdccd6"/>
|
id="rect11"
|
||||||
<path d="m 55.101065,32.189965 9.2711,-15.0623 c 0.1866,-0.3072 -0.16,-0.6546 -0.4666,-0.4675 l -14.4431,8.9371 c -0.3865,0.2405 -0.6998,0.5678 -0.9264,0.9619 l -8.038,14.027 h 40.1634 c 0.3932,0 0.4732,-0.5544 0.1,-0.668 z" fill="#94bfcf"/>
|
style="fill:url(#pageGrad)" />
|
||||||
<path d="m 54.507965,48.641565 -14.0099,-8.0555 v 40.2507 c 0,0.3941 0.5532,0.4742 0.6665,0.1002 l 7.7181,-25.7094 15.0296,9.2912 c 0.3066,0.187 0.6532,-0.1603 0.4665,-0.4676 l -8.9177,-14.4812 c -0.2333,-0.3807 -0.5666,-0.7013 -0.9531,-0.9284 z" fill="#eee9d9"/>
|
<rect
|
||||||
</g>
|
x="104"
|
||||||
<!-- Title -->
|
y="84"
|
||||||
<text x="103" y="180" text-anchor="middle" font-family="Georgia, serif" font-size="15" font-weight="bold" fill="#ffffff" letter-spacing="1">TOREAD</text>
|
width="318"
|
||||||
<line x1="55" y1="188" x2="151" y2="188" stroke="#ffffff50" stroke-width="0.8"/>
|
height="318"
|
||||||
<text x="103" y="202" text-anchor="middle" font-family="Georgia, serif" font-size="9" fill="#aaccdd" letter-spacing="2">E-READER</text>
|
rx="10"
|
||||||
<!-- Bottom spine detail -->
|
fill="#ece9df"
|
||||||
<rect x="18" y="228" width="18" height="16" fill="#0e2030"/>
|
id="rect12" />
|
||||||
|
<rect
|
||||||
|
x="96"
|
||||||
|
y="76"
|
||||||
|
width="318"
|
||||||
|
height="318"
|
||||||
|
rx="10"
|
||||||
|
fill="#f0ede3"
|
||||||
|
id="rect13" />
|
||||||
|
</g>
|
||||||
|
<rect
|
||||||
|
x="121.15213"
|
||||||
|
y="128.76512"
|
||||||
|
width="42.381393"
|
||||||
|
height="262.06592"
|
||||||
|
rx="7.8484058"
|
||||||
|
fill="url(#spineGrad)"
|
||||||
|
id="rect14"
|
||||||
|
style="fill:url(#spineGrad);stroke:none;stroke-width:0.755863" />
|
||||||
|
<rect
|
||||||
|
x="151.69673"
|
||||||
|
y="129.02002"
|
||||||
|
width="235.62991"
|
||||||
|
height="261.811"
|
||||||
|
rx="7.2725282"
|
||||||
|
fill="url(#coverGrad)"
|
||||||
|
id="rect15"
|
||||||
|
style="fill:url(#coverGrad);stroke-width:0.727253" />
|
||||||
|
<rect
|
||||||
|
x="151.69673"
|
||||||
|
y="129.02002"
|
||||||
|
width="235.62991"
|
||||||
|
height="261.811"
|
||||||
|
rx="7.2725282"
|
||||||
|
fill="url(#coverShine)"
|
||||||
|
id="rect16"
|
||||||
|
style="display:inline;fill:url(#coverShine);stroke-width:0.727253" />
|
||||||
|
<line
|
||||||
|
x1="160.42378"
|
||||||
|
y1="136.29254"
|
||||||
|
x2="160.42378"
|
||||||
|
y2="383.5585"
|
||||||
|
stroke="#00000030"
|
||||||
|
stroke-width="1.45451"
|
||||||
|
id="line16" />
|
||||||
|
<rect
|
||||||
|
x="162.24403"
|
||||||
|
y="141.29759"
|
||||||
|
width="215.68887"
|
||||||
|
height="240.71645"
|
||||||
|
rx="4.6888885"
|
||||||
|
fill="none"
|
||||||
|
stroke="#ffffff30"
|
||||||
|
stroke-width="3.10595"
|
||||||
|
id="rect17"
|
||||||
|
style="fill:none;stroke:#000000;stroke-opacity:0.104098" />
|
||||||
|
<g
|
||||||
|
transform="matrix(2.5090222,0,0,2.5090222,168.42356,158.11013)"
|
||||||
|
id="g20">
|
||||||
|
<path
|
||||||
|
d="m 32.120065,25.957965 -15.0296,-9.2912 c -0.3066,-0.187 -0.6532,0.1603 -0.4666,0.4676 l 8.9112,14.4745 c 0.2399,0.3874 0.5665,0.7013 0.9597,0.9284 l 14.0032,8.0555 V 0.34209525 c 0,-0.394094 -0.5532,-0.474248 -0.6665,-0.1002 z"
|
||||||
|
fill="#6197b4"
|
||||||
|
id="path17" />
|
||||||
|
<path
|
||||||
|
d="m 25.901665,48.988865 -9.271,15.0556 c -0.1866,0.3073 0.16,0.6546 0.4665,0.4676 l 14.4431,-8.9305 c 0.3866,-0.2405 0.6999,-0.5678 0.9265,-0.9619 l 8.038,-14.0336 H 0.34134532 c -0.393231,0 -0.473212,0.5544 -0.09997,0.6679 z"
|
||||||
|
fill="#bdccd6"
|
||||||
|
id="path18" />
|
||||||
|
<path
|
||||||
|
d="m 55.101065,32.189965 9.2711,-15.0623 c 0.1866,-0.3072 -0.16,-0.6546 -0.4666,-0.4675 l -14.4431,8.9371 c -0.3865,0.2405 -0.6998,0.5678 -0.9264,0.9619 l -8.038,14.027 h 40.1634 c 0.3932,0 0.4732,-0.5544 0.1,-0.668 z"
|
||||||
|
fill="#94bfcf"
|
||||||
|
id="path19" />
|
||||||
|
<path
|
||||||
|
d="m 54.507965,48.641565 -14.0099,-8.0555 v 40.2507 c 0,0.3941 0.5532,0.4742 0.6665,0.1002 l 7.7181,-25.7094 15.0296,9.2912 c 0.3066,0.187 0.6532,-0.1603 0.4665,-0.4676 l -8.9177,-14.4812 c -0.2333,-0.3807 -0.5666,-0.7013 -0.9531,-0.9284 z"
|
||||||
|
fill="#eee9d9"
|
||||||
|
id="path20" />
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 7.0 KiB |
BIN
image_src/playstore-icon.png
Normal file
|
After Width: | Height: | Size: 212 KiB |