Skip to content

Commit 703fb87

Browse files
authored
Merge pull request #13 from whatrushki/develop
🚀 release: promote develop to main for v1.0.5
2 parents 2757098 + 33306d9 commit 703fb87

119 files changed

Lines changed: 1807 additions & 1421 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
/.idea/navEditor.xml
99
/.idea/assetWizardSettings.xml
1010
.DS_Store
11-
/build
11+
build
1212
/captures
1313
.externalNativeBuild
1414
.cxx

app/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ android {
2929
minSdk = 26
3030
targetSdk = 36
3131
versionCode = generateVersionCode()
32-
versionName = "1.0.4-beta.1"
32+
versionName = "1.0.5"
3333

3434
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
3535
vectorDrawables {

app/src/main/java/app/what/schedule/CrashActivity.kt

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,20 +35,20 @@ import java.io.File
3535
class CrashActivity : ComponentActivity() {
3636
override fun onCreate(savedInstanceState: Bundle?) {
3737
super.onCreate(savedInstanceState)
38-
38+
3939
Auditor.critic("app.crash", intent.getStringExtra("CRASH_REPORT") ?: "")
40-
40+
4141
enableEdgeToEdge()
4242
setContent {
4343
// НЕ ПЕРЕМЕЩАТЬ!!
4444
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
4545
window.setNavigationBarContrastEnforced(false)
4646
}
47-
47+
4848
AppTheme(koinInject<AppValues>()) {
4949
ProvideGlobalDialog {
5050
val dialog = rememberDialogController()
51-
51+
5252
Box {
5353
FloatingActionButton(
5454
modifier = Modifier
@@ -62,7 +62,7 @@ class CrashActivity : ComponentActivity() {
6262
) {
6363
WHATIcons.FrameBug.Show(color = colorScheme.onSecondaryContainer)
6464
}
65-
65+
6666
CrashScreen(
6767
crashReport = intent.getStringExtra("CRASH_REPORT") ?: "",
6868
onRestart = { restartApp() },
@@ -73,7 +73,7 @@ class CrashActivity : ComponentActivity() {
7373
}
7474
}
7575
}
76-
76+
7777
private fun restartApp() {
7878
val intent = packageManager.getLaunchIntentForPackage(packageName)?.apply {
7979
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
@@ -82,21 +82,21 @@ class CrashActivity : ComponentActivity() {
8282
finish()
8383
Process.killProcess(Process.myPid())
8484
}
85-
85+
8686
private fun shareCrashReport() {
8787
val crashReport = intent.getStringExtra("CRASH_REPORT") ?: return
88-
88+
8989
try {
9090
val file = File(cacheDir, "crash_report.txt")
9191
file.writeText(crashReport)
92-
92+
9393
val uris = listOf(
9494
getFileUri(file),
9595
).let {
9696
if (Auditor.logFile.exists()) it + getFileUri(Auditor.logFile)
9797
else it
9898
}
99-
99+
100100
ShareUtils.shareUris(
101101
this@CrashActivity,
102102
ArrayList(uris)
@@ -105,7 +105,7 @@ class CrashActivity : ComponentActivity() {
105105
Toast.makeText(this, "Error sharing report", Toast.LENGTH_SHORT).show()
106106
}
107107
}
108-
108+
109109
private fun getFileUri(file: File) =
110110
FileProvider.getUriForFile(this, "${packageName}.fileprovider", file)
111111
}

app/src/main/java/app/what/schedule/MainActivity.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,22 @@ import org.koin.compose.koinInject
2828

2929
class MainActivity : ComponentActivity() {
3030
private val crashlytics = FirebaseCrashlytics.getInstance()
31-
31+
3232
override fun onCreate(savedInstanceState: Bundle?) {
3333
super.onCreate(savedInstanceState)
34-
34+
3535
val uiTag = buildTag(LogScope.UI, LogCat.INIT)
3636
Auditor.info(uiTag, "MainActivity создана")
37-
37+
3838
enableEdgeToEdge()
3939
setContent {
4040
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
4141
window.setNavigationBarContrastEnforced(false)
4242
}
43-
43+
4444
val navigator = rememberHostNavigator()
4545
val settings = koinInject<AppValues>()
46-
46+
4747
LaunchedEffect(Unit) {
4848
navigator.c.addOnDestinationChangedListener { _, destination, _ ->
4949
val navTag = buildTag(LogScope.CORE, LogCat.NAV)
@@ -52,7 +52,7 @@ class MainActivity : ComponentActivity() {
5252
crashlytics.setCustomKey("current_screen", destination.route ?: "unknown")
5353
}
5454
}
55-
55+
5656
ProvideGLobalAppValues(settings) {
5757
AppTheme {
5858
ProvideGlobalDialog {

app/src/main/java/app/what/schedule/ScheduleApp.kt

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import com.google.firebase.analytics.analytics
4343
import com.google.firebase.crashlytics.FirebaseCrashlytics
4444
import io.ktor.client.HttpClient
4545
import io.ktor.client.engine.cio.CIO
46+
import io.ktor.client.plugins.HttpRequestRetry
4647
import io.ktor.client.plugins.HttpTimeout
4748
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
4849
import io.ktor.client.plugins.logging.Logger
@@ -65,29 +66,29 @@ import javax.net.ssl.X509TrustManager
6566
class ScheduleApp : Application() {
6667
override fun onCreate() {
6768
super.onCreate()
68-
69+
6970
if (FirebaseApp.getApps(this).isEmpty()) {
7071
FirebaseApp.initializeApp(this)
7172
}
72-
73+
7374
val crashlytics = FirebaseCrashlytics.getInstance()
7475
crashlytics.setCustomKey("app_version", BuildConfig.VERSION_NAME)
7576
crashlytics.setCustomKey("app_version_code", BuildConfig.VERSION_CODE)
76-
77+
7778
AppLogger.initialize(applicationContext)
7879
CrashHandler.initialize(applicationContext, CrashActivity::class.java)
7980
.setSideEffect(crashlytics::recordException)
80-
81+
8182
val initTag = buildTag(LogScope.CORE, LogCat.INIT)
8283
Auditor.info(initTag, "Приложение запущено")
83-
84+
8485
startKoin {
8586
androidContext(this@ScheduleApp)
8687
modules(generalModule, controllers)
8788
}
88-
89+
8990
val koin = getKoin()
90-
91+
9192
val appValues = koin.get<AppValues>()
9293
if (appValues.userId.get() == null) {
9394
val userId = UUID.randomUUID().toString()
@@ -98,7 +99,7 @@ class ScheduleApp : Application() {
9899
} else {
99100
Auditor.debug(initTag, "Пользователь уже существует: ${appValues.userId.get()}")
100101
}
101-
102+
102103
SingletonImageLoader.setSafe {
103104
ImageLoader.Builder(this)
104105
.crossfade(true)
@@ -107,9 +108,9 @@ class ScheduleApp : Application() {
107108
}
108109
.build()
109110
}
110-
111+
111112
val source = getInstallSource(this)
112-
113+
113114
when (source) {
114115
InstallSource.APK -> Auditor.debug("d", "install source Apk")
115116
InstallSource.RuStore -> Auditor.debug("d", "install source RuStore")
@@ -129,24 +130,24 @@ val controllers = module {
129130

130131
val generalModule = module {
131132
single<CoroutineScope> { CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate) }
132-
133+
133134
singleOf(::AppValues) bind PreferenceStorage::class
134135
singleOf(::AppUtils)
135136
singleOf(::GoogleDriveParser)
136137
singleOf(::FileManager)
137-
138+
138139
singleOf(::DGTUAccountService)
139-
140+
140141
singleOf(::InstitutionManager)
141142
singleOf(::ScheduleRepository)
142143
singleOf(::NewsRepository)
143-
144+
144145
single<AppUpdateManager> {
145146
val context = androidContext()
146147
val source = getInstallSource(context)
147-
148+
148149
when (source) {
149-
150+
150151
InstallSource.RuStore -> RuStoreUpdateManager(context, get())
151152
InstallSource.APK -> GitHubUpdateManager(
152153
GitHubUpdateService(get()),
@@ -160,7 +161,7 @@ val generalModule = module {
160161
)
161162
}
162163
}
163-
164+
164165
single {
165166
Room.databaseBuilder(
166167
androidContext(),
@@ -170,19 +171,36 @@ val generalModule = module {
170171
.fallbackToDestructiveMigration(true)
171172
.build()
172173
}
173-
174+
174175
single {
175176
HttpClient(CIO) {
177+
install(HttpRequestRetry) {
178+
maxRetries = 4
179+
180+
retryOnExceptionIf { _, cause ->
181+
cause is java.net.UnknownHostException ||
182+
cause is java.net.ConnectException ||
183+
cause is java.net.SocketTimeoutException
184+
}
185+
186+
retryOnServerErrors(maxRetries = 3)
187+
188+
exponentialDelay(
189+
baseDelayMs = 300L,
190+
maxDelayMs = 5000L
191+
)
192+
}
193+
176194
install(NetworkMonitorPlugin)
177-
195+
178196
install(Logging) {
179197
logger = object : Logger {
180198
override fun log(message: String) {
181199
Auditor.debug(buildTag(LogScope.NETWORK, LogCat.NET), message)
182200
}
183201
}
184202
}
185-
203+
186204
install(ContentNegotiation) {
187205
json(Json {
188206
classDiscriminator = "type"
@@ -192,12 +210,12 @@ val generalModule = module {
192210
explicitNulls = false
193211
})
194212
}
195-
213+
196214
install(HttpTimeout) {
197215
this@HttpClient.expectSuccess = false
198216
requestTimeoutMillis = 60 * 1000
199217
}
200-
218+
201219
engine {
202220
https {
203221
trustManager = object : X509TrustManager {
@@ -206,13 +224,13 @@ val generalModule = module {
206224
authType: String
207225
) {
208226
}
209-
227+
210228
override fun checkServerTrusted(
211229
chain: Array<X509Certificate>,
212230
authType: String
213231
) {
214232
}
215-
233+
216234
override fun getAcceptedIssuers(): Array<X509Certificate> = arrayOf()
217235
}
218236
}

app/src/main/java/app/what/schedule/data/local/database/Converters.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,44 +10,44 @@ import java.time.format.DateTimeFormatterBuilder
1010
class Converters {
1111
private val dateFormatter = DateTimeFormatter.ISO_LOCAL_DATE
1212
private val timeFormatter = DateTimeFormatter.ISO_LOCAL_TIME
13-
13+
1414
// Существует два основных подхода для LocalDateTime:
15-
15+
1616
// Подход 1: Использовать ISO_LOCAL_DATE_TIME (рекомендуется)
1717
private val dateTimeFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME
18-
18+
1919
// Подход 2: Разделить дату и время компонентами (альтернативный вариант)
2020
private val customDateTimeFormatter = DateTimeFormatterBuilder()
2121
.append(DateTimeFormatter.ISO_LOCAL_DATE)
2222
.appendLiteral(' ')
2323
.append(DateTimeFormatter.ISO_LOCAL_TIME)
2424
.toFormatter()
25-
25+
2626
@TypeConverter
2727
fun fromLocalDate(date: LocalDate?): String? {
2828
return date?.format(dateFormatter)
2929
}
30-
30+
3131
@TypeConverter
3232
fun toLocalDate(dateString: String?): LocalDate? {
3333
return dateString?.let { LocalDate.parse(it, dateFormatter) }
3434
}
35-
35+
3636
@TypeConverter
3737
fun fromLocalTime(time: LocalTime?): String? {
3838
return time?.format(timeFormatter)
3939
}
40-
40+
4141
@TypeConverter
4242
fun toLocalTime(timeString: String?): LocalTime? {
4343
return timeString?.let { LocalTime.parse(it, timeFormatter) }
4444
}
45-
45+
4646
@TypeConverter
4747
fun fromLocalDateTime(dateTime: LocalDateTime?): String? {
4848
return dateTime?.format(dateTimeFormatter)
4949
}
50-
50+
5151
@TypeConverter
5252
fun toLocalDateTime(dateTimeString: String?): LocalDateTime? {
5353
return dateTimeString?.let { LocalDateTime.parse(it, dateTimeFormatter) }

0 commit comments

Comments
 (0)