Compare commits

..
Author SHA1 Message Date
Agzamus dea27bc8f1 ci: fixed workflow old apt jdk17 repo 2026-09-07 00:35:50 +03:00
Agzamus bafebfd253 fix: no auto download if updated disabled 2026-09-07 00:31:34 +03:00
Agzamus f19d65abb5 feat: update request when need 2026-09-06 17:23:55 +03:00
Agzamus 889c57bbba feat: autoupdater 2026-09-06 12:38:00 +03:00
Agzamus ec6a7174e8 feat: icon & name 2026-09-06 02:47:40 +03:00
32 changed files with 401 additions and 92 deletions
+11 -2
View File
@@ -29,10 +29,19 @@ jobs:
- name: Set up JDK 17 - name: Set up JDK 17
# Ставим JDK вручную и явно прописываем JAVA_HOME. # Ставим JDK вручную и явно прописываем JAVA_HOME.
# actions/setup-java не всегда передаёт JAVA_HOME дальше в Gitea Actions. # actions/setup-java не всегда передаёт JAVA_HOME дальше в Gitea Actions.
# JDK качаем из архива Adoptium напрямую: образ раннера — Debian bullseye,
# его репозитории уже в архиве, apt-установка openjdk падает с 404.
run: | run: |
set -euxo pipefail
apt-get update apt-get update
apt-get install -y openjdk-17-jdk-headless unzip wget apt-get install -y --no-install-recommends wget unzip
echo "JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64" >> "$GITHUB_ENV" mkdir -p /opt/jdk
wget -qO /tmp/jdk17.tar.gz \
"https://api.adoptium.net/v3/binary/latest/17/ga/linux/x64/jdk/hotspot/normal/eclipse"
tar -xzf /tmp/jdk17.tar.gz -C /opt/jdk --strip-components=1
echo "JAVA_HOME=/opt/jdk" >> "$GITHUB_ENV"
echo "/opt/jdk/bin" >> "$GITHUB_PATH"
/opt/jdk/bin/java -version
- name: Install Android SDK - name: Install Android SDK
# Устанавливаем command-line tools и нужные компоненты SDK, # Устанавливаем command-line tools и нужные компоненты SDK,
+1 -5
View File
@@ -1,6 +1,2 @@
# vyatsu-schedulegit # vyatsu-schedule
## settings-branch
blank settings at first, soon will add update feature.
settings will be presetned as fourth button on the bottom of the screen.
+1 -1
View File
@@ -10,7 +10,7 @@
android:allowBackup="true" android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules" android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules" android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher" android:icon="@drawable/icon"
android:label="@string/app_name" android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
Binary file not shown.

Before

Width:  |  Height:  |  Size: 234 KiB

+27
View File
@@ -6,6 +6,9 @@ import agzam.vyatsu.ui.groups.GroupPickerViewModel
import agzam.vyatsu.ui.home.HomeScreen import agzam.vyatsu.ui.home.HomeScreen
import agzam.vyatsu.ui.schedule.ScheduleViewModel import agzam.vyatsu.ui.schedule.ScheduleViewModel
import agzam.vyatsu.ui.settings.UpdateViewModel import agzam.vyatsu.ui.settings.UpdateViewModel
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
@@ -24,6 +27,30 @@ fun AppRoot() {
val updateViewModel: UpdateViewModel = viewModel(factory = updateFactory(container)) val updateViewModel: UpdateViewModel = viewModel(factory = updateFactory(container))
val state by scheduleViewModel.uiState.collectAsState() val state by scheduleViewModel.uiState.collectAsState()
val showFirstRunDialog by updateViewModel.showFirstRunDialog.collectAsState()
if (showFirstRunDialog) {
AlertDialog(
onDismissRequest = { updateViewModel.onFirstRunDecision(false) },
title = { Text("Автоматические обновления") },
text = {
Text(
"Разрешить автоматически проверять и устанавливать " +
"новые версии приложения?"
)
},
confirmButton = {
TextButton(onClick = { updateViewModel.onFirstRunDecision(true) }) {
Text("Разрешить")
}
},
dismissButton = {
TextButton(onClick = { updateViewModel.onFirstRunDecision(false) }) {
Text("Не надо")
}
}
)
}
if (state.noGroup) { if (state.noGroup) {
GroupPickerScreen( GroupPickerScreen(
@@ -33,4 +33,10 @@ interface PreferencesDao {
@Query("INSERT OR REPLACE INTO preferences(key, value) VALUES('autoUpdateEnabled', :enabled)") @Query("INSERT OR REPLACE INTO preferences(key, value) VALUES('autoUpdateEnabled', :enabled)")
suspend fun setAutoUpdateEnabled(enabled: String) suspend fun setAutoUpdateEnabled(enabled: String)
@Query("SELECT value FROM preferences WHERE key = 'autoUpdateAsked'")
suspend fun autoUpdateAsked(): String?
@Query("INSERT OR REPLACE INTO preferences(key, value) VALUES('autoUpdateAsked', :asked)")
suspend fun setAutoUpdateAsked(asked: String)
} }
@@ -14,6 +14,9 @@ class PreferencesRepositoryImpl(
override suspend fun selectedDayDate(): String? = dao.selectedDayDate() override suspend fun selectedDayDate(): String? = dao.selectedDayDate()
override suspend fun setSelectedDayDate(date: String) = dao.setSelectedDayDate(date) override suspend fun setSelectedDayDate(date: String) = dao.setSelectedDayDate(date)
override suspend fun autoUpdateEnabled(): Boolean = dao.autoUpdateEnabled() != "false" override suspend fun autoUpdateEnabled(): Boolean = dao.autoUpdateEnabled() == "true"
override suspend fun setAutoUpdateEnabled(enabled: Boolean) = dao.setAutoUpdateEnabled(enabled.toString()) override suspend fun setAutoUpdateEnabled(enabled: Boolean) = dao.setAutoUpdateEnabled(enabled.toString())
override suspend fun autoUpdateAsked(): Boolean = dao.autoUpdateAsked() == "true"
override suspend fun setAutoUpdateAsked(asked: Boolean) = dao.setAutoUpdateAsked(asked.toString())
} }
@@ -11,4 +11,7 @@ interface PreferencesRepository {
suspend fun autoUpdateEnabled(): Boolean suspend fun autoUpdateEnabled(): Boolean
suspend fun setAutoUpdateEnabled(enabled: Boolean) suspend fun setAutoUpdateEnabled(enabled: Boolean)
suspend fun autoUpdateAsked(): Boolean
suspend fun setAutoUpdateAsked(asked: Boolean)
} }
@@ -50,12 +50,12 @@ fun SettingsScreen(viewModel: UpdateViewModel) {
item { item {
SettingsItem( SettingsItem(
title = "Проверить наличие обновлений", title = "Проверить наличие обновлений",
subtitle = updateStatusText(updateState), subtitle = updateStatusText(updateState, autoEnabled),
onClick = { viewModel.checkNow() } onClick = { viewModel.checkNow() }
) )
SettingsDivider() SettingsDivider()
} }
if (updateState is UpdateState.Available || updateState is UpdateState.ReadyToInstall) { if (autoEnabled && (updateState is UpdateState.Available || updateState is UpdateState.ReadyToInstall)) {
item { item {
SettingsItem( SettingsItem(
title = "Установить обновление", title = "Установить обновление",
@@ -89,11 +89,13 @@ fun SettingsScreen(viewModel: UpdateViewModel) {
} }
} }
private fun updateStatusText(state: UpdateState): String = when (state) { private fun updateStatusText(state: UpdateState, autoEnabled: Boolean): String = when (state) {
is UpdateState.Idle -> "Проверить сейчас" is UpdateState.Idle -> "Проверить сейчас"
is UpdateState.Checking -> "Проверка…" is UpdateState.Checking -> "Проверка…"
is UpdateState.UpToDate -> "Установлена последняя версия" is UpdateState.UpToDate -> "Установлена последняя версия"
is UpdateState.Available -> "Доступна версия ${state.version}" is UpdateState.Available ->
if (autoEnabled) "Доступна версия ${state.version}"
else "Доступна версия ${state.version} — включите автообновления для установки"
is UpdateState.Downloading -> "Скачивание: ${state.progress?.let { "$it%" } ?: "…"}" is UpdateState.Downloading -> "Скачивание: ${state.progress?.let { "$it%" } ?: "…"}"
is UpdateState.ReadyToInstall -> "Обновление скачано, нажмите для установки" is UpdateState.ReadyToInstall -> "Обновление скачано, нажмите для установки"
is UpdateState.Failed -> "Ошибка: ${state.message}" is UpdateState.Failed -> "Ошибка: ${state.message}"
@@ -17,18 +17,33 @@ class UpdateViewModel(
val updateState: StateFlow<UpdateState> = updater.state val updateState: StateFlow<UpdateState> = updater.state
private val _autoEnabled = MutableStateFlow(true) private val _autoEnabled = MutableStateFlow(false)
val autoEnabled: StateFlow<Boolean> = _autoEnabled.asStateFlow() val autoEnabled: StateFlow<Boolean> = _autoEnabled.asStateFlow()
private val _showFirstRunDialog = MutableStateFlow(false)
val showFirstRunDialog: StateFlow<Boolean> = _showFirstRunDialog.asStateFlow()
init { init {
viewModelScope.launch { viewModelScope.launch {
_autoEnabled.value = preferencesRepository.autoUpdateEnabled() _autoEnabled.value = preferencesRepository.autoUpdateEnabled()
_showFirstRunDialog.value = !preferencesRepository.autoUpdateAsked()
} }
} }
fun setAutoEnabled(enabled: Boolean) { fun setAutoEnabled(enabled: Boolean) {
_autoEnabled.value = enabled _autoEnabled.value = enabled
updater.setAutoEnabled(enabled) updater.setAutoEnabled(enabled)
if (enabled && !updater.canRequestInstalls()) {
updater.openUnknownSourcesSettings()
}
}
fun onFirstRunDecision(enable: Boolean) {
_showFirstRunDialog.value = false
viewModelScope.launch {
preferencesRepository.setAutoUpdateAsked(true)
}
setAutoEnabled(enable)
} }
fun checkNow() = updater.checkForUpdate() fun checkNow() = updater.checkForUpdate()
@@ -9,6 +9,7 @@ import android.net.Uri
import android.provider.Settings import android.provider.Settings
import android.util.Log import android.util.Log
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import kotlin.coroutines.cancellation.CancellationException
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
@@ -75,6 +76,7 @@ class AppUpdater(
if (job?.isActive == true) return if (job?.isActive == true) return
val update = pendingUpdate ?: return val update = pendingUpdate ?: return
job = scope.launch { job = scope.launch {
if (!preferencesRepository.autoUpdateEnabled()) return@launch
runCatching { install(download(update)) }.onFailure(::onUpdateFailed) runCatching { install(download(update)) }.onFailure(::onUpdateFailed)
} }
} }
@@ -85,6 +87,12 @@ class AppUpdater(
} }
fun setAutoEnabled(enabled: Boolean) { fun setAutoEnabled(enabled: Boolean) {
if (!enabled) {
job?.cancel()
if (_state.value is UpdateState.Downloading || _state.value is UpdateState.Checking) {
_state.value = UpdateState.Idle
}
}
scope.launch { scope.launch {
preferencesRepository.setAutoUpdateEnabled(enabled) preferencesRepository.setAutoUpdateEnabled(enabled)
} }
@@ -166,7 +174,6 @@ class AppUpdater(
private fun install(apk: File) { private fun install(apk: File) {
if (!canRequestInstalls()) { if (!canRequestInstalls()) {
openUnknownSourcesSettings()
return return
} }
val uri = FileProvider.getUriForFile( val uri = FileProvider.getUriForFile(
@@ -184,6 +191,7 @@ class AppUpdater(
} }
private fun onUpdateFailed(error: Throwable) { private fun onUpdateFailed(error: Throwable) {
if (error is CancellationException) throw error
Log.e(TAG, "Ошибка обновления", error) Log.e(TAG, "Ошибка обновления", error)
_state.value = UpdateState.Failed(error.message ?: "Неизвестная ошибка") _state.value = UpdateState.Failed(error.message ?: "Неизвестная ошибка")
} }
@@ -1,74 +1,170 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<vector <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="108dp"
android:width="108dp" android:width="108dp"
android:viewportHeight="108" android:height="108dp"
android:viewportWidth="108" android:viewportWidth="108"
xmlns:android="http://schemas.android.com/apk/res/android"> android:viewportHeight="108">
<path android:fillColor="#3DDC84" <path
android:pathData="M0,0h108v108h-108z"/> android:fillColor="#3DDC84"
<path android:fillColor="#00000000" android:pathData="M9,0L9,108" android:pathData="M0,0h108v108h-108z" />
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> <path
<path android:fillColor="#00000000" android:pathData="M19,0L19,108" android:fillColor="#00000000"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:pathData="M9,0L9,108"
<path android:fillColor="#00000000" android:pathData="M29,0L29,108" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:strokeColor="#33FFFFFF" />
<path android:fillColor="#00000000" android:pathData="M39,0L39,108" <path
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:fillColor="#00000000"
<path android:fillColor="#00000000" android:pathData="M49,0L49,108" android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:strokeWidth="0.8"
<path android:fillColor="#00000000" android:pathData="M59,0L59,108" android:strokeColor="#33FFFFFF" />
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> <path
<path android:fillColor="#00000000" android:pathData="M69,0L69,108" android:fillColor="#00000000"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:pathData="M29,0L29,108"
<path android:fillColor="#00000000" android:pathData="M79,0L79,108" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:strokeColor="#33FFFFFF" />
<path android:fillColor="#00000000" android:pathData="M89,0L89,108" <path
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:fillColor="#00000000"
<path android:fillColor="#00000000" android:pathData="M99,0L99,108" android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:strokeWidth="0.8"
<path android:fillColor="#00000000" android:pathData="M0,9L108,9" android:strokeColor="#33FFFFFF" />
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> <path
<path android:fillColor="#00000000" android:pathData="M0,19L108,19" android:fillColor="#00000000"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:pathData="M49,0L49,108"
<path android:fillColor="#00000000" android:pathData="M0,29L108,29" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:strokeColor="#33FFFFFF" />
<path android:fillColor="#00000000" android:pathData="M0,39L108,39" <path
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:fillColor="#00000000"
<path android:fillColor="#00000000" android:pathData="M0,49L108,49" android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:strokeWidth="0.8"
<path android:fillColor="#00000000" android:pathData="M0,59L108,59" android:strokeColor="#33FFFFFF" />
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> <path
<path android:fillColor="#00000000" android:pathData="M0,69L108,69" android:fillColor="#00000000"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:pathData="M69,0L69,108"
<path android:fillColor="#00000000" android:pathData="M0,79L108,79" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:strokeColor="#33FFFFFF" />
<path android:fillColor="#00000000" android:pathData="M0,89L108,89" <path
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:fillColor="#00000000"
<path android:fillColor="#00000000" android:pathData="M0,99L108,99" android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:strokeWidth="0.8"
<path android:fillColor="#00000000" android:pathData="M19,29L89,29" android:strokeColor="#33FFFFFF" />
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> <path
<path android:fillColor="#00000000" android:pathData="M19,39L89,39" android:fillColor="#00000000"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:pathData="M89,0L89,108"
<path android:fillColor="#00000000" android:pathData="M19,49L89,49" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:strokeColor="#33FFFFFF" />
<path android:fillColor="#00000000" android:pathData="M19,59L89,59" <path
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:fillColor="#00000000"
<path android:fillColor="#00000000" android:pathData="M19,69L89,69" android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:strokeWidth="0.8"
<path android:fillColor="#00000000" android:pathData="M19,79L89,79" android:strokeColor="#33FFFFFF" />
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> <path
<path android:fillColor="#00000000" android:pathData="M29,19L29,89" android:fillColor="#00000000"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:pathData="M0,9L108,9"
<path android:fillColor="#00000000" android:pathData="M39,19L39,89" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:strokeColor="#33FFFFFF" />
<path android:fillColor="#00000000" android:pathData="M49,19L49,89" <path
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:fillColor="#00000000"
<path android:fillColor="#00000000" android:pathData="M59,19L59,89" android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:strokeWidth="0.8"
<path android:fillColor="#00000000" android:pathData="M69,19L69,89" android:strokeColor="#33FFFFFF" />
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> <path
<path android:fillColor="#00000000" android:pathData="M79,19L79,89" android:fillColor="#00000000"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> 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" />
</vector> </vector>
+109
View File
@@ -0,0 +1,109 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="100dp"
android:height="100dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:pathData="M1,6L1,18L19,18L19,6"
android:strokeLineJoin="round"
android:strokeWidth="0"
android:strokeLineCap="round">
<aapt:attr name="android:fillColor">
<gradient
android:startX="1"
android:startY="18"
android:endX="19"
android:endY="6"
android:type="linear">
<item android:offset="0" android:color="#FF5581D5"/>
<item android:offset="1" android:color="#FF4063CD"/>
</gradient>
</aapt:attr>
<aapt:attr name="android:strokeColor">
<gradient
android:startX="1"
android:startY="18"
android:endX="19"
android:endY="6"
android:type="linear">
<item android:offset="0" android:color="#FF5581D5"/>
<item android:offset="1" android:color="#FF4063CD"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M19,18L1,18C12,18 19,14 19,6Z"
android:strokeLineJoin="round"
android:strokeWidth="0"
android:strokeLineCap="round">
<aapt:attr name="android:fillColor">
<gradient
android:startX="1"
android:startY="18"
android:endX="19"
android:endY="6"
android:type="linear">
<item android:offset="0" android:color="#FF6598E3"/>
<item android:offset="1" android:color="#FF74A2E6"/>
</gradient>
</aapt:attr>
<aapt:attr name="android:strokeColor">
<gradient
android:startX="1"
android:startY="18"
android:endX="19"
android:endY="6"
android:type="linear">
<item android:offset="0" android:color="#FF6598E3"/>
<item android:offset="1" android:color="#FF74A2E6"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M4,4C4,2 6,2 6,4L14,4C14,2 16,2 16,4L19,4L19,6L1,6L1,4Z"
android:strokeLineJoin="round"
android:strokeWidth="0"
android:strokeLineCap="round">
<aapt:attr name="android:fillColor">
<gradient
android:startX="1"
android:startY="2.5"
android:endX="19"
android:endY="2.5"
android:type="linear">
<item android:offset="0" android:color="#FF4260C4"/>
<item android:offset="1" android:color="#FF0E2CB0"/>
</gradient>
</aapt:attr>
<aapt:attr name="android:strokeColor">
<gradient
android:startX="1"
android:startY="2.5"
android:endX="19"
android:endY="2.5"
android:type="linear">
<item android:offset="0" android:color="#FF4260C4"/>
<item android:offset="1" android:color="#FF0E2CB0"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M3,8L17,8C18,8 18,9 17,9L3,9C2,9 2,8 3,8M3,11L14,11C15,11 15,12 14,12L3,12C2,12 2,11 3,11M4,14L12,14C13,14 13,15 12,15L5,15C4,15 4,14 5,14M3,14C4,14 4,15 3,15C2,15 2,14 3,14"
android:strokeLineJoin="round"
android:strokeWidth="0"
android:strokeColor="#00000000"
android:strokeLineCap="round">
<aapt:attr name="android:fillColor">
<gradient
android:startX="2.25"
android:startY="8"
android:endX="17.75"
android:endY="8"
android:type="linear">
<item android:offset="0" android:color="#FF4260C4"/>
<item android:offset="1" android:color="#FF0E2CB0"/>
</gradient>
</aapt:attr>
</path>
</vector>
+35
View File
@@ -0,0 +1,35 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100px" height="100px" viewBox="-10 -10 20 20">
<defs>
<linearGradient id="accent">
<stop offset="0%" stop-color="#4260c4" />
<stop offset="100%" stop-color="#0e2cb0" />
</linearGradient>
<linearGradient id="bg" x1="0%" y1="100%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#5581d5" />
<stop offset="100%" stop-color="#4063cd" />
</linearGradient>
<linearGradient id="bga" x1="0%" y1="100%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#6598e3" />
<stop offset="100%" stop-color="#74a2e6" />
</linearGradient>
</defs>
<g stroke-width="0" stroke-linejoin="round" stroke-linecap="round">
<!-- <path stroke="#111" d="M -9 -4 L -9 8 L 9 8 L 9 -4"/> -->
<path stroke="url(#bg)" fill="url(#bg)" d="M -9 -4 L -9 8 L 9 8 L 9 -4"/>
<path stroke="url(#bga)" fill="url(#bga)" d="M 9 8 L -9 8 C 2 8 9 4 9 -4 Z"/>
<!-- <path stroke="#111" d="M -6 -6 C -6 -8 -4 -8 -4 -6 L 4 -6 C 4 -8 6 -8 6 -6 L 9 -6 L 9 -4 L -9 -4 L -9 -6 Z"/> -->
<g stroke="url(#accent)">
<path fill="url(#accent)" d="M -6 -6 C -6 -8 -4 -8 -4 -6 L 4 -6 C 4 -8 6 -8 6 -6 L 9 -6 L 9 -4 L -9 -4 L -9 -6 Z"/>
<path fill="url(#accent)" stroke="none" d="M -7 -2 L 7 -2 C 8 -2 8 -1 7 -1 L -7 -1 C -8 -1 -8 -2 -7 -2 M -7 1 L 4 1 C 5 1 5 2 4 2 L -7 2 C -8 2 -8 1 -7 1 M -6 4 L 2 4 C 3 4 3 5 2 5 L -5 5 C -6 5 -6 4 -5 4 M -7 4 C -6 4 -6 5 -7 5 C -8 5 -8 4 -7 4"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

@@ -1,6 +1,6 @@
<?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="@drawable/ic_launcher_background" />
<foreground android:drawable="@mipmap/ic_launcher_foreground"/> <foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@mipmap/ic_launcher_foreground"/> <monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon> </adaptive-icon>
@@ -1,6 +1,6 @@
<?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="@drawable/ic_launcher_background" />
<foreground android:drawable="@mipmap/ic_launcher_foreground"/> <foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@mipmap/ic_launcher_foreground"/> <monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon> </adaptive-icon>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

+1 -1
View File
@@ -1,3 +1,3 @@
<resources> <resources>
<string name="app_name">VyatsuSchedule</string> <string name="app_name">ВятГУ Расписание</string>
</resources> </resources>