diff --git a/.gitignore b/.gitignore old mode 100755 new mode 100644 index ea7022d..aa724b7 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,15 @@ -*.swp -TODO.md -./.idea/ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..43452ec --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/mobile/.gitignore b/mobile/.gitignore deleted file mode 100644 index aa724b7..0000000 --- a/mobile/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -*.iml -.gradle -/local.properties -/.idea/caches -/.idea/libraries -/.idea/modules.xml -/.idea/workspace.xml -/.idea/navEditor.xml -/.idea/assetWizardSettings.xml -.DS_Store -/build -/captures -.externalNativeBuild -.cxx -local.properties diff --git a/mobile/.idea/.gitignore b/mobile/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/mobile/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/mobile/.idea/.name b/mobile/.idea/.name index 99e1610..990c379 100644 --- a/mobile/.idea/.name +++ b/mobile/.idea/.name @@ -1 +1 @@ -Solon \ No newline at end of file +solon \ No newline at end of file diff --git a/mobile/.idea/assetWizardSettings.xml b/mobile/.idea/assetWizardSettings.xml new file mode 100644 index 0000000..ac10bc1 --- /dev/null +++ b/mobile/.idea/assetWizardSettings.xml @@ -0,0 +1,297 @@ + + + + + + \ No newline at end of file diff --git a/mobile/.idea/codeStyles/Project.xml b/mobile/.idea/codeStyles/Project.xml deleted file mode 100644 index 7643783..0000000 --- a/mobile/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/mobile/.idea/codeStyles/codeStyleConfig.xml b/mobile/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index 79ee123..0000000 --- a/mobile/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/mobile/.idea/deploymentTargetDropDown.xml b/mobile/.idea/deploymentTargetDropDown.xml deleted file mode 100644 index 0c0c338..0000000 --- a/mobile/.idea/deploymentTargetDropDown.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/mobile/.idea/deploymentTargetSelector.xml b/mobile/.idea/deploymentTargetSelector.xml index 5a312d0..bec964a 100644 --- a/mobile/.idea/deploymentTargetSelector.xml +++ b/mobile/.idea/deploymentTargetSelector.xml @@ -4,15 +4,18 @@ + + \ No newline at end of file diff --git a/mobile/.idea/inspectionProfiles/Project_Default.xml b/mobile/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..005afb3 --- /dev/null +++ b/mobile/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,47 @@ + + + + \ No newline at end of file diff --git a/mobile/.idea/kotlinc.xml b/mobile/.idea/kotlinc.xml index 8d81632..031f228 100644 --- a/mobile/.idea/kotlinc.xml +++ b/mobile/.idea/kotlinc.xml @@ -1,6 +1,16 @@ + + + + + + - \ No newline at end of file diff --git a/mobile/.idea/material_theme_project_new.xml b/mobile/.idea/material_theme_project_new.xml new file mode 100644 index 0000000..9d92b58 --- /dev/null +++ b/mobile/.idea/material_theme_project_new.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/mobile/.idea/misc.xml b/mobile/.idea/misc.xml index 02a7102..b2c751a 100644 --- a/mobile/.idea/misc.xml +++ b/mobile/.idea/misc.xml @@ -1,7 +1,9 @@ - + + \ No newline at end of file diff --git a/mobile/.idea/vcs.xml b/mobile/.idea/vcs.xml index 6c0b863..8a1c0ed 100644 --- a/mobile/.idea/vcs.xml +++ b/mobile/.idea/vcs.xml @@ -1,6 +1,7 @@ - + + \ No newline at end of file diff --git a/mobile/app/build.gradle.kts b/mobile/app/build.gradle.kts index 8054883..bfb5f44 100644 --- a/mobile/app/build.gradle.kts +++ b/mobile/app/build.gradle.kts @@ -1,6 +1,7 @@ plugins { - id("com.android.application") - id("org.jetbrains.kotlin.android") + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.compose) } android { @@ -12,39 +13,42 @@ android { minSdk = 28 targetSdk = 34 versionCode = 1 - versionName = "1.0.9" + versionName = "2.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { isMinifyEnabled = false - proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) } } compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = "1.8" + jvmTarget = "11" } buildFeatures { - viewBinding = true + compose = true } } dependencies { - implementation("androidx.core:core-ktx:1.12.0") - implementation("androidx.appcompat:appcompat:1.6.1") - implementation("com.google.android.material:material:1.11.0") - implementation("androidx.constraintlayout:constraintlayout:2.1.4") - implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.7.0") - implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0") - implementation("androidx.navigation:navigation-fragment-ktx:2.7.7") - implementation("androidx.navigation:navigation-ui-ktx:2.7.7") - implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.7.0") - implementation("com.squareup.okhttp3:okhttp:4.12.0") - implementation("androidx.viewpager2:viewpager2:1.0.0") - implementation("com.github.bumptech.glide:glide:4.16.0") - implementation("com.google.android.material:material:1.11.0") + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.lifecycle.runtime.ktx) + implementation(libs.androidx.activity.compose) + implementation(platform(libs.androidx.compose.bom)) + implementation(libs.androidx.ui) + implementation(libs.androidx.ui.graphics) + implementation(libs.androidx.ui.tooling.preview) + implementation(libs.androidx.material3) + implementation(libs.okhttp) + implementation(libs.glide) + implementation(libs.androidx.material.icons.extended) } \ No newline at end of file diff --git a/mobile/app/release/baselineProfiles/0/app-release.dm b/mobile/app/release/baselineProfiles/0/app-release.dm new file mode 100644 index 0000000..68e52a9 Binary files /dev/null and b/mobile/app/release/baselineProfiles/0/app-release.dm differ diff --git a/mobile/app/release/baselineProfiles/1/app-release.dm b/mobile/app/release/baselineProfiles/1/app-release.dm new file mode 100644 index 0000000..11e8fa4 Binary files /dev/null and b/mobile/app/release/baselineProfiles/1/app-release.dm differ diff --git a/mobile/app/release/output-metadata.json b/mobile/app/release/output-metadata.json new file mode 100644 index 0000000..8c787b5 --- /dev/null +++ b/mobile/app/release/output-metadata.json @@ -0,0 +1,37 @@ +{ + "version": 3, + "artifactType": { + "type": "APK", + "kind": "Directory" + }, + "applicationId": "com.odweta.solon", + "variantName": "release", + "elements": [ + { + "type": "SINGLE", + "filters": [], + "attributes": [], + "versionCode": 1, + "versionName": "2.0", + "outputFile": "app-release.apk" + } + ], + "elementType": "File", + "baselineProfiles": [ + { + "minApi": 28, + "maxApi": 30, + "baselineProfiles": [ + "baselineProfiles/1/app-release.dm" + ] + }, + { + "minApi": 31, + "maxApi": 2147483647, + "baselineProfiles": [ + "baselineProfiles/0/app-release.dm" + ] + } + ], + "minSdkVersionForDexing": 28 +} \ No newline at end of file diff --git a/mobile/app/src/main/AndroidManifest.xml b/mobile/app/src/main/AndroidManifest.xml index 987f655..ca28995 100644 --- a/mobile/app/src/main/AndroidManifest.xml +++ b/mobile/app/src/main/AndroidManifest.xml @@ -10,29 +10,23 @@ android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" - android:icon="@mipmap/ic_launcher" - android:label="@string/app_name" - android:roundIcon="@mipmap/ic_launcher_round" + android:icon="@mipmap/launcher" + android:label="Solon" + android:roundIcon="@mipmap/launcher_round" android:supportsRtl="true" android:theme="@style/Theme.Solon" - tools:targetApi="tiramisu" - android:usesCleartextTraffic="true" - android:enableOnBackInvokedCallback="true"> + tools:targetApi="31"> + android:label="@string/app_name" + android:theme="@style/Theme.Solon"> - \ No newline at end of file diff --git a/mobile/app/src/main/gitlab_logo-playstore.png b/mobile/app/src/main/gitlab_logo-playstore.png deleted file mode 100644 index 51220e5..0000000 Binary files a/mobile/app/src/main/gitlab_logo-playstore.png and /dev/null differ diff --git a/mobile/app/src/main/grade-playstore.png b/mobile/app/src/main/grade-playstore.png deleted file mode 100644 index 52a120a..0000000 Binary files a/mobile/app/src/main/grade-playstore.png and /dev/null differ diff --git a/mobile/app/src/main/grade2-playstore.png b/mobile/app/src/main/grade2-playstore.png deleted file mode 100644 index 4142987..0000000 Binary files a/mobile/app/src/main/grade2-playstore.png and /dev/null differ diff --git a/mobile/app/src/main/ic_launcher-playstore.png b/mobile/app/src/main/ic_launcher-playstore.png deleted file mode 100644 index 6f21e06..0000000 Binary files a/mobile/app/src/main/ic_launcher-playstore.png and /dev/null differ diff --git a/mobile/app/src/main/java/com/odweta/solon/About.kt b/mobile/app/src/main/java/com/odweta/solon/About.kt new file mode 100644 index 0000000..0ddaa67 --- /dev/null +++ b/mobile/app/src/main/java/com/odweta/solon/About.kt @@ -0,0 +1,129 @@ +package com.odweta.solon + +import androidx.compose.foundation.Image +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.Row +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.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowBackIosNew +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalUriHandler +import com.odweta.solon.ui.theme.PastelYellow +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextDecoration +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import java.time.format.TextStyle + +@Composable +fun AboutScreen(modifier: Modifier = Modifier) { + Column( + modifier = Modifier + .fillMaxSize(), + verticalArrangement = Arrangement.Top, + horizontalAlignment = Alignment.Start + ) { + Box( + modifier = Modifier + .fillMaxWidth() + ) { + Button( + onClick = { + isShowing.value = IsShowing.Menu + }, + colors = ButtonDefaults.buttonColors( + contentColor = Color.White, + containerColor = Color.Black + ), + modifier = Modifier + .border( + width = 5.dp, + shape = RoundedCornerShape(roundedCornerDimen), + color = PastelYellow + ) + .width(100.dp) + .height(100.dp) + ) { + Icon( + imageVector = Icons.Default.ArrowBackIosNew, // Replace with your desired icon + contentDescription = "Back icon", + modifier = Modifier.size(35.dp) // Adjust size if needed + ) + } + } + + Column( + modifier = Modifier.fillMaxWidth(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + Image( + painter = painterResource(R.drawable.solon_just_yellow), + contentDescription = "Solon logo", + modifier = Modifier.size(200.dp) + ) + + Text( + text = "Přehlednost je podstata", + color = Color.White, + fontSize = 30.sp, + fontStyle = FontStyle.Italic, + modifier = Modifier + .padding(10.dp) + ) + + Text( + text = "Odlehčená verze mobilní aplikace Škola OnLine", + color = Color.White, + textAlign = TextAlign.Center, + fontSize = 25.sp, + modifier = Modifier + .padding(10.dp) + ) + + Row( + modifier = Modifier + .padding(10.dp) + ) { + val uriHandler = LocalUriHandler.current + + Text( + text = "Vývoj: ", + textAlign = TextAlign.Start, + color = Color.White, + fontSize = 30.sp + ) + + Text( + text = "@Odweta", + color = PastelYellow, + fontSize = 30.sp, + textAlign = TextAlign.End, + textDecoration = TextDecoration.Underline, + modifier = Modifier.clickable { + uriHandler.openUri("https://www.gitlab.com/Odweta/solon") + } + ) + } + } + } +} \ No newline at end of file diff --git a/mobile/app/src/main/java/com/odweta/solon/AboutFragment.kt b/mobile/app/src/main/java/com/odweta/solon/AboutFragment.kt deleted file mode 100644 index d304727..0000000 --- a/mobile/app/src/main/java/com/odweta/solon/AboutFragment.kt +++ /dev/null @@ -1,145 +0,0 @@ -package com.odweta.solon - -import android.app.Dialog -import android.content.Intent -import android.net.Uri -import android.os.Bundle -import android.text.Spannable -import android.text.SpannableString -import android.text.method.LinkMovementMethod -import android.text.style.ClickableSpan -import android.text.style.UnderlineSpan -import android.view.GestureDetector -import android.view.LayoutInflater -import android.view.MotionEvent -import android.view.View -import android.view.ViewGroup -import android.view.Window -import android.widget.TextView -import android.widget.Toast -import androidx.fragment.app.DialogFragment -import kotlin.math.abs - - -class AboutFragment : DialogFragment() { - private lateinit var gestureDetector: GestureDetector - private var initialTouchY: Float = 0f - private val swipeThreshold = 100 - private val swipeVelocityThreshold = 100 - private lateinit var dialog: Dialog - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setStyle(STYLE_NORMAL, R.style.Theme_Solon) - } - - override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? - ): View? { - val view = inflater.inflate(R.layout.activity_about, container, false) - - // Set up GestureDetector - gestureDetector = GestureDetector(requireContext(), SwipeGestureListener()) - - // Attach the gesture detector to the root layout - view.setOnTouchListener { _, event -> - view.performClick() - handleTouchEvent(event) - } - - val link = view.findViewById(R.id.link) - val underlinedText = SpannableString(link.text) - underlinedText.setSpan(UnderlineSpan(), 8, link.text.length, 0) - - link.text = underlinedText - makeTextViewClickable(link, "https://gitlab.com/Odweta", 8) - - - val srcLink = view.findViewById(R.id.sourceCode) - val underlinedText2 = SpannableString(srcLink.text) - underlinedText2.setSpan(UnderlineSpan(), 1, srcLink.text.length, 0) - - srcLink.text = underlinedText2 - makeTextViewClickable(srcLink, "https://gitlab.com/Odweta/solon") - - return view - } - - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - dialog = super.onCreateDialog(savedInstanceState) - dialog.window?.attributes?.windowAnimations = R.style.Theme_Solon_DialogAnimation - dialog.window?.requestFeature(Window.FEATURE_NO_TITLE) - dialog.setCancelable(true) - - return dialog - } - - private fun makeTextViewClickable(link: TextView, url: String, offset: Int = 0) { - val clickableSpan = object : ClickableSpan() { - override fun onClick(widget: View) { - if (Vars.internetAvail) { - val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) - startActivity(intent) - } else { - Toast.makeText( - requireContext(), - "Bez připojení k internetu.", - Toast.LENGTH_SHORT - ).show() - } - } - } - - val spannable = Spannable.Factory.getInstance().newSpannable(link.text) - spannable.setSpan(clickableSpan, offset, link.text.length, Spannable.SPAN_COMPOSING) - - link.text = spannable - link.movementMethod = LinkMovementMethod.getInstance() - } - - inner class SwipeGestureListener : GestureDetector.SimpleOnGestureListener() { - override fun onDown(e: MotionEvent): Boolean { - return true - } - - override fun onFling( - e1: MotionEvent?, - e2: MotionEvent, - velocityX: Float, - velocityY: Float - ): Boolean { - val diffY = e1?.let { e2.y.minus(it.y) } ?: 0f - if (diffY > swipeThreshold && abs(velocityY) > swipeVelocityThreshold) { - // Swiped down - dismiss() - return true - } - return false - } - } - - @Suppress("SameReturnValue", "SameReturnValue", "SameReturnValue") - private fun handleTouchEvent(event: MotionEvent): Boolean { - when (event.action) { - MotionEvent.ACTION_DOWN -> { - initialTouchY = event.rawY - } - MotionEvent.ACTION_MOVE -> { - val deltaY = event.rawY - initialTouchY - dialog?.window?.attributes?.y = deltaY.toInt() - dialog?.window?.attributes?.windowAnimations = 0 - dialog?.show() - - // Check if the dialog has been dragged beyond a threshold and dismiss if necessary - if (deltaY > 200) { - dismiss() - } - } - MotionEvent.ACTION_UP -> { - initialTouchY = 0f - } - } - return true - } -} \ No newline at end of file diff --git a/mobile/app/src/main/java/com/odweta/solon/Account.kt b/mobile/app/src/main/java/com/odweta/solon/Account.kt index c2b1746..14db999 100644 --- a/mobile/app/src/main/java/com/odweta/solon/Account.kt +++ b/mobile/app/src/main/java/com/odweta/solon/Account.kt @@ -27,7 +27,7 @@ class Account(val username: String, val password: String, private val error: Int */ // check if file exists - val file = File(Vars.fileDir, Vars.accountDataFilePath) + val file = File(fileDir, accountDataFilePath) return if (!file.exists()) { // it does not exist @@ -36,15 +36,15 @@ class Account(val username: String, val password: String, private val error: Int } else { // it exists, so it shall be parsed val acc: Account = parseAccountDataFile(file) - Vars.username = acc.username - Vars.password = acc.password + username = acc.username + password = acc.password acc.error == 0 } } fun save(acc: Account): Boolean { return try { - val file = File(Vars.fileDir, Vars.accountDataFilePath) + val file = File(fileDir, accountDataFilePath) file.writeText("${acc.username}\n${acc.password}\n", Charset.forName("UTF-8")) true @@ -55,8 +55,8 @@ class Account(val username: String, val password: String, private val error: Int suspend fun isValid(acc: Account): Boolean { return withContext(Dispatchers.IO) { - Vars.username = acc.username - Vars.password = acc.password + username = acc.username + password = acc.password val token = Network.getToken() !JSONObject(token).has("error") diff --git a/mobile/app/src/main/java/com/odweta/solon/CalWeekFragment.kt b/mobile/app/src/main/java/com/odweta/solon/CalWeekFragment.kt deleted file mode 100644 index cc1b6b6..0000000 --- a/mobile/app/src/main/java/com/odweta/solon/CalWeekFragment.kt +++ /dev/null @@ -1,751 +0,0 @@ -package com.odweta.solon - -import android.annotation.SuppressLint -import android.content.res.Resources -import android.graphics.Typeface -import android.graphics.drawable.GradientDrawable -import android.os.Bundle -import android.os.Handler -import android.os.Looper -import android.util.Log -import android.view.Gravity -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.view.ViewTreeObserver -import android.widget.FrameLayout -import android.widget.ImageView -import android.widget.LinearLayout -import android.widget.ScrollView -import android.widget.Space -import android.widget.TextView -import androidx.core.content.ContextCompat -import androidx.core.content.res.ResourcesCompat -import androidx.core.view.marginLeft -import androidx.core.view.setMargins -import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentManager -import androidx.lifecycle.Lifecycle -import androidx.viewpager2.adapter.FragmentStateAdapter -import androidx.viewpager2.widget.ViewPager2 -import java.time.LocalDate -import java.time.LocalTime -class CalWeekFragment : Fragment() { - private lateinit var viewPager: ViewPager2 - private lateinit var adapter: DayPagerAdapter - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View? { - val view = inflater.inflate(R.layout.activity_cal_week, container, false) - - viewPager = view.findViewById(R.id.dayPager) - - adapter = DayPagerAdapter(childFragmentManager, viewLifecycleOwner.lifecycle) - - Vars.dayCounter = 0 - for (i in 0 until Vars.days.size) { - adapter.addFragment(DayFragment()) - } - - viewPager.viewTreeObserver.addOnPreDrawListener { - viewPager.currentItem = Vars.selectedDay - true - } - - viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { - override fun onPageSelected(position: Int) { - super.onPageSelected(position) - if (viewPager.isLaidOut) { - Vars.selectedDay = position - } - } - }) - - viewPager.adapter = adapter - viewPager.offscreenPageLimit = adapter.itemCount - - return view - } -} - -class DayPagerAdapter(fragmentManager: FragmentManager, lifecycle: Lifecycle) : - FragmentStateAdapter(fragmentManager, lifecycle) { - - private val fragmentList = mutableListOf() - - fun addFragment(fragment: Fragment) { - fragmentList.add(fragment) - } - - override fun getItemCount(): Int { - return fragmentList.size - } - - override fun createFragment(position: Int): Fragment { - return fragmentList[position] - } -} - -class DayFragment : Fragment() { - private val handler = Handler(Looper.getMainLooper()) - - @SuppressLint("ClickableViewAccessibility") - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View? { - val view = inflater.inflate(R.layout.fragment_day, container, false) - - val dayLayout: LinearLayout = view.findViewById(R.id.layoutDayMain) - createDayView(Vars.dayList[Vars.dayCounter], dayLayout, resources) - Vars.dayCounter += 1 - - return view - } - - private fun highlightCurrent( - subj: Subject, - day: Day, - subjectDrawable: GradientDrawable, - subjectStroke: Int, - i: Int - ) { - handler.postDelayed(object : Runnable { - override fun run() { - subjectDrawable.setStroke(0, 0) - - val now = LocalTime.now() - val nowD = LocalDate.now().dayOfMonth - val nowH = now.hour - val nowM = now.minute - val nowT = LocalTime.of(nowH, nowM) - - lateinit var subjST: LocalTime - lateinit var subjET: LocalTime - val subjD = day.date.split(".")[0].toInt() - - if ("T" !in subj.start && "T" !in subj.end) { - val subjSH = subj.start.split(":")[0].toInt() - val subjSM = subj.start.split(":")[1].toInt() - - val subjEH = subj.end.split(":")[0].toInt() - val subjEM = subj.end.split(":")[1].toInt() - - subjST = LocalTime.of(subjSH, subjSM) - subjET = LocalTime.of(subjEH, subjEM) - } else { - val subjSH = subj.start - .split("T")[1] - .split(":")[0] - .toInt() - val subjSM = subj.start - .split("T")[1] - .split(":")[1] - .toInt() - - val subjEH = subj.end - .split("T")[1] - .split(":")[0] - .toInt() - val subjEM = subj.end - .split("T")[1] - .split(":")[1] - .toInt() - - subjST = LocalTime.of(subjSH, subjSM) - subjET = LocalTime.of(subjEH, subjEM) - } - - if ( - nowT in subjST..subjET && - nowD == subjD - ) { - if (i < day.subjects.size - 1 && !day.subjects[i + 1].free && !subj.free) { - subjectDrawable.setStroke( - 10, - ContextCompat.getColor( - requireContext(), - subjectStroke - ) - ) - } else if (i < day.subjects.size - 1 && day.subjects[i + 1].free && nowT != subjET) { - subjectDrawable.setStroke( - 10, - ContextCompat.getColor( - requireContext(), - subjectStroke - ) - ) - } else if (i < day.subjects.size - 1 && subj.free && !day.subjects[i + 1].free && nowT != subjET) { - subjectDrawable.setStroke( - 10, - ContextCompat.getColor( - requireContext(), - subjectStroke - ) - ) - } else if (i == day.subjects.size - 1) { - subjectDrawable.setStroke( - 10, - ContextCompat.getColor( - requireContext(), - subjectStroke - ) - ) - } - } else if ( - nowD == subjD && - i > 0 - ) { - lateinit var prevET: LocalTime - - val prev = day.subjects[i - 1] - if ("T" !in prev.start && "T" !in prev.end) { - val prevEH = prev.end - .split(":")[0] - .toInt() - val prevEM = prev.end - .split(":")[1] - .toInt() - - prevET = LocalTime.of(prevEH, prevEM) - } else { - val prevEH = prev.end - .split("T")[1] - .split(":")[0] - .toInt() - val prevEM = prev.end - .split("T")[1] - .split(":")[1] - .toInt() - - prevET = LocalTime.of(prevEH, prevEM) - } - - if ( - nowT < subjST && - nowT > prevET - ) { - subjectDrawable.setStroke( - 10, - ContextCompat.getColor( - requireContext(), - subjectStroke - ) - ) - } - } - - requireView().postInvalidate() - // repeat every second - handler.postDelayed(this, 1000L) - } - }, 0L) - } - - override fun onDestroyView() { - super.onDestroyView() - // Stop updating UI when the view is destroyed - handler.removeCallbacksAndMessages(null) - } - - @SuppressLint("UseCompatLoadingForDrawables") - private fun createDayView(day: Day, rootLayout: LinearLayout, resources: Resources) { - val customFont = context?.let { ResourcesCompat.getFont(it, R.font.roboto) } - - val scrollView = ScrollView(requireContext()) - scrollView.scrollBarStyle = R.style.Theme_Solon_Scrollbar - - val dayLayout = LinearLayout(requireContext()) - dayLayout.orientation = LinearLayout.VERTICAL - - val nameDateTextView = TextView(requireContext()) - nameDateTextView.text = String.format("%s %s", day.name, day.date) - nameDateTextView.setTypeface(customFont, Typeface.BOLD_ITALIC) - //nameDateTextView.textSize = 28f - nameDateTextView.setTextColor( - ContextCompat.getColor( - requireContext(), - R.color.white - ) - ) - nameDateTextView.setPadding(10, 0, 10, 40) - nameDateTextView.gravity = Gravity.CENTER_HORIZONTAL - - rootLayout.addView(nameDateTextView) - - var prevSubj = Subject() - prevSubj.name = "" - prevSubj.place = "" - prevSubj.substitute = "" - prevSubj.teacher = "" - prevSubj.number = "" - prevSubj.start = "" - prevSubj.end = "" - prevSubj.free = false - - for ((i, subj) in day.subjects.withIndex()) { - val subjectBackground = when (subj.substitute) { - "0" -> if (subj.place != "Volno") { - R.color.primary_transparent_bg - } else { - R.color.cal_week_free_transparent_bg - } - "1" -> if (subj.place != "Volno") { - R.color.cal_week_substitute_transparent_bg - } else { - R.color.cal_week_free_transparent_bg - } - "2" -> if (subj.place != "Volno") { - R.color.cal_week_event_transparent_bg - } else { - R.color.cal_week_free_transparent_bg - } - else -> R.color.primary_transparent_bg - } - - val subjectStroke = when (subj.substitute) { - "0" -> if (subj.place != "Volno") { - R.color.primary - } else { - R.color.cal_week_free - } - "1" -> if (subj.place != "Volno") { - R.color.cal_week_substitute - } else { - R.color.cal_week_free - } - "2" -> if (subj.place != "Volno") { - R.color.cal_week_event - } else { - R.color.cal_week_free - } - else -> R.color.primary - } - - val subjectDrawable = GradientDrawable() - subjectDrawable.shape = GradientDrawable.RECTANGLE - subjectDrawable.cornerRadius = - resources.getDimension(R.dimen.corner_radius) // Specify corner radius in resources - subjectDrawable.setColor( - ContextCompat.getColor( - requireContext(), - subjectBackground - ) - ) - - // launch a periodic check for highlighting the current lecture - highlightCurrent(subj, day, subjectDrawable, subjectStroke, i) - - - val subjectLayout = LinearLayout(requireContext()) - subjectLayout.orientation = LinearLayout.HORIZONTAL - subjectLayout.gravity = Gravity.CENTER_VERTICAL - subjectLayout.background = subjectDrawable - - // height specifier - val heightSpecifier = View(requireContext()) - heightSpecifier.layoutParams = LinearLayout.LayoutParams( - 0, - 160 - ) - - subjectLayout.addView(heightSpecifier) - - val subjectNumberDrawable = GradientDrawable() - subjectNumberDrawable.shape = GradientDrawable.RECTANGLE - subjectNumberDrawable.cornerRadius = resources.getDimension(R.dimen.corner_radius) - subjectNumberDrawable.setColor( - ContextCompat.getColor( - requireContext(), - subjectBackground - ) - ) - - val subjectNumberTextView = TextView(requireContext()) - subjectNumberTextView.typeface = customFont - subjectNumberTextView.text = subj.number - //subjectNumberTextView.textSize = 33f - subjectNumberTextView.setPadding(20, 20, 20, 20) - subjectNumberTextView.gravity = Gravity.CENTER // Center text vertically - subjectNumberTextView.setTextColor( - ContextCompat.getColor( - requireContext(), - R.color.white - ) - ) - subjectNumberTextView.background = subjectNumberDrawable - - val frameLayout = FrameLayout(requireContext()) - val layoutParams = LinearLayout.LayoutParams( - 120, - FrameLayout.LayoutParams.MATCH_PARENT, - ) - frameLayout.foregroundGravity = Gravity.CENTER - frameLayout.layoutParams = layoutParams - - frameLayout.addView(subjectNumberTextView) - - if (subj.substitute != "2") { - subjectLayout.addView(frameLayout) - } - - val namePlaceLL = LinearLayout(requireContext()) - namePlaceLL.orientation = LinearLayout.VERTICAL - - val subjectNameTextView = TextView(requireContext()) - if (subj.name != "Volno") { - subjectNameTextView.text = subj.name.uppercase() - } - subjectNameTextView.setTypeface(customFont, Typeface.BOLD) - //subjectNameTextView.textSize = 29f - subjectNameTextView.setPadding(0, 0, 0, 0) - subjectNameTextView.gravity = Gravity.CENTER_VERTICAL - subjectNameTextView.setTextColor( - ContextCompat.getColor( - requireContext(), - R.color.white - ) - ) - - if (!subj.free) { - namePlaceLL.addView(subjectNameTextView) - } - - val subjectPlaceTextView = TextView(requireContext()) - subjectPlaceTextView.typeface = customFont - subjectPlaceTextView.text = subj.place - subjectPlaceTextView.setPadding(0, 0, 0, 0) - if (subj.free) { - // italic - subjectPlaceTextView.setTypeface(customFont, Typeface.ITALIC) - subjectPlaceTextView.text = "Volno " - } - //subjectPlaceTextView.textSize = 22f - subjectPlaceTextView.gravity = Gravity.CENTER_VERTICAL - subjectPlaceTextView.setTextColor( - ContextCompat.getColor( - requireContext(), - R.color.white - ) - ) - - if (subj.substitute != "2") { - namePlaceLL.addView(subjectPlaceTextView) - } - - namePlaceLL.setPadding(30, 15, 20, 15) - - subjectLayout.addView(namePlaceLL) - - if (subj.teacher == "Jindřich Svoboda") { - val img = ImageView(requireContext()) - img.setImageDrawable(resources.getDrawable(R.drawable.spock)) - val frameLayout2 = FrameLayout(requireContext()) - val layoutParams2 = LinearLayout.LayoutParams( - 100, - 120, - ) - frameLayout2.foregroundGravity = Gravity.CENTER - frameLayout2.layoutParams = layoutParams2 - - frameLayout2.addView(img) - subjectLayout.addView(frameLayout2) - } - - val params = LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - LinearLayout.LayoutParams.MATCH_PARENT - ) - params.gravity = Gravity.END - - val timeTeacherLayout = LinearLayout(requireContext()) - timeTeacherLayout.orientation = LinearLayout.VERTICAL - timeTeacherLayout.layoutParams = params - timeTeacherLayout.gravity = Gravity.CENTER_VERTICAL - - val subjectTimeTextView = TextView(requireContext()) - val subjectTimeString = subj.start + "–" + subj.end - subjectTimeTextView.typeface = customFont - subjectTimeTextView.text = subjectTimeString - //subjectTimeTextView.textSize = 20f - subjectTimeTextView.setPadding(10, 0, 20, 0) - subjectTimeTextView.gravity = Gravity.END - subjectTimeTextView.isSingleLine = true - subjectTimeTextView.textAlignment = View.TEXT_ALIGNMENT_TEXT_END - subjectTimeTextView.setTextColor( - ContextCompat.getColor( - requireContext(), - R.color.white - ) - ) - - val subjectTeacherTextView = TextView(requireContext()) - subjectTeacherTextView.text = subj.teacher - subjectTeacherTextView.typeface = customFont - //subjectTeacherTextView.textSize = 15f - subjectTeacherTextView.setPadding(0, 10, 20, 10) - subjectTeacherTextView.textAlignment = View.TEXT_ALIGNMENT_TEXT_END - subjectTeacherTextView.setTextColor( - ContextCompat.getColor( - requireContext(), - R.color.white - ) - ) - - timeTeacherLayout.addView(subjectTimeTextView) - if (subj.name != "Volno") { - subjectTimeTextView.setPadding(0, 10, 20, 0) - timeTeacherLayout.addView(subjectTeacherTextView) - } - timeTeacherLayout.setPadding(0, 0, 10, 0) - - if (subj.substitute != "2") { - subjectLayout.addView(timeTeacherLayout) - } - - // drawables - val substituteDrawable = GradientDrawable() - substituteDrawable.shape = GradientDrawable.RECTANGLE - substituteDrawable.cornerRadius = resources.getDimension(R.dimen.corner_radius) - substituteDrawable.setColor( - ContextCompat.getColor( - requireContext(), - R.color.cal_week_substitute - ) - ) - - val eventDrawable = GradientDrawable() - eventDrawable.shape = GradientDrawable.RECTANGLE - eventDrawable.cornerRadius = resources.getDimension(R.dimen.corner_radius) - eventDrawable.setColor( - ContextCompat.getColor( - requireContext(), - R.color.cal_week_event - ) - ) - - // Attach an OnPreDrawListener to the rootLayout's ViewTreeObserver - rootLayout.viewTreeObserver.addOnPreDrawListener(object : - ViewTreeObserver.OnPreDrawListener { - override fun onPreDraw(): Boolean { - // Remove the listener to avoid multiple callbacks - rootLayout.viewTreeObserver.removeOnPreDrawListener(this) - - // Call your function or perform an action here - if (subj.free) { - subjectPlaceTextView.text = "Volno " - } - - nameDateTextView.layoutParams = LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - LinearLayout.LayoutParams.WRAP_CONTENT - ) - - if (subj.substitute == "2") { - namePlaceLL.textAlignment = View.TEXT_ALIGNMENT_CENTER - namePlaceLL.setPadding(0, 0, 0, 0) - subjectNameTextView.layoutParams = LinearLayout.LayoutParams( - subjectLayout.width, - LinearLayout.LayoutParams.MATCH_PARENT - ) - subjectNameTextView.textAlignment = View.TEXT_ALIGNMENT_CENTER - subjectNameTextView.gravity = Gravity.CENTER_VERTICAL - } - - // Return true to continue with the drawing, or false to cancel - return true - } - }) - - val subjectLayoutParams = LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - LinearLayout.LayoutParams.WRAP_CONTENT - ) - subjectLayoutParams.setMargins( - resources.getDimensionPixelSize(R.dimen.cal_week_separator_height)/4, - 0, - resources.getDimensionPixelSize(R.dimen.cal_week_separator_height)/4, - 0 - ) - subjectLayout.layoutParams = subjectLayoutParams - - if (prevSubj.name != subj.name && i != 0) { - val subjectSeparator = Space(requireContext()) - subjectSeparator.layoutParams = LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - resources.getDimensionPixelSize(R.dimen.cal_week_separator_height) // Specify separator height in resources - ) - - dayLayout.addView(subjectSeparator) - } else if (i != 0) { - val subjectSeparator = ImageView(requireContext()) - subjectSeparator.setImageResource(R.drawable.squiggly_line_100_yellow_transparent_one_color_edge) - subjectSeparator.layoutParams = LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - resources.getDimensionPixelSize(R.dimen.cal_week_separator_height) - ) - - dayLayout.addView(subjectSeparator) - } - - subjectNumberTextView.textSize = resources.getDimension(R.dimen.text_size_subject_number) / resources.displayMetrics.scaledDensity - subjectNameTextView.textSize = resources.getDimension(R.dimen.text_size_subject_name) / resources.displayMetrics.scaledDensity - if (subj.free) { - subjectPlaceTextView.textSize = - resources.getDimension(R.dimen.text_size_subject_place_free) / resources.displayMetrics.scaledDensity - } else { - subjectPlaceTextView.textSize = - resources.getDimension(R.dimen.text_size_subject_place) / resources.displayMetrics.scaledDensity - } - subjectTimeTextView.textSize = resources.getDimension(R.dimen.text_size_subject_time) / resources.displayMetrics.scaledDensity - subjectTeacherTextView.textSize = resources.getDimension(R.dimen.text_size_subject_teacher) / resources.displayMetrics.scaledDensity - - dayLayout.addView(subjectLayout) - - prevSubj = subj - } - - val subjectSeparator = Space(requireContext()) - subjectSeparator.layoutParams = LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - resources.getDimensionPixelSize(R.dimen.cal_week_separator_height) // Specify separator height in resources - ) - - dayLayout.addView(subjectSeparator) - - val dayEndTextView = TextView(requireContext()) - val endTime = day.subjects[day.subjects.size - 1].end - Vars.dayEndString = "Den končí v $endTime" - dayEndTextView.text = Vars.dayEndString - dayEndTextView.typeface = customFont - //dayEndTextView.setAutoSizeTextTypeUniformWithConfiguration(55, 85, 1, 0) - dayEndTextView.setPadding(0, 25, 0, 25) - dayEndTextView.textAlignment = View.TEXT_ALIGNMENT_CENTER - dayEndTextView.gravity = Gravity.CENTER - dayEndTextView.setTextColor( - ContextCompat.getColor( - requireContext(), - R.color.white - ) - ) - - val dayEndDrawable = GradientDrawable() - dayEndDrawable.shape = GradientDrawable.RECTANGLE - dayEndDrawable.cornerRadius = resources.getDimension((R.dimen.corner_radius)) - dayEndDrawable.setColor( - ContextCompat.getColor( - requireContext(), - R.color.primary_transparent_bg - ) - ) - dayEndDrawable.setStroke( - 10, - ContextCompat.getColor( - requireContext(), - R.color.primary - ) - ) - dayEndTextView.background = dayEndDrawable - - val dayEndSeparator = Space(requireContext()) - dayEndSeparator.layoutParams = LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - resources.getDimensionPixelSize(R.dimen.cal_week_separator_height) // Specify separator height in resources - ) - val dayEndSeparator2 = Space(requireContext()) - dayEndSeparator2.layoutParams = LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - resources.getDimensionPixelSize(R.dimen.cal_week_separator_height) // Specify separator height in resources - ) - - val endParams = LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - 130 - ) - endParams.setMargins( - resources.getDimensionPixelSize(R.dimen.cal_week_separator_height)/4, - 0, - resources.getDimensionPixelSize(R.dimen.cal_week_separator_height)/4, - 0 - ) - dayEndTextView.layoutParams = endParams - - dayLayout.addView(dayEndSeparator) - dayLayout.addView(dayEndTextView) - dayLayout.addView(dayEndSeparator2) - - scrollView.addView(dayLayout) - - rootLayout.addView(scrollView) - - // fill in the rest with empty space - val sepr = Space(requireContext()) - sepr.layoutParams = LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - Vars.height - rootLayout.height - ) - - rootLayout.addView(sepr) - - nameDateTextView.textSize = resources.getDimension(R.dimen.text_size_name_date) / resources.displayMetrics.scaledDensity - dayEndTextView.textSize = resources.getDimension(R.dimen.text_size_day_end) / resources.displayMetrics.scaledDensity - } -} - -class Subject { - lateinit var name: String - lateinit var place: String - lateinit var teacher: String - lateinit var substitute: String - lateinit var number: String - lateinit var start: String - lateinit var end: String - var free: Boolean = false - - companion object { - fun freeSubject(number: String, start: String, end: String): Subject { - val s = Subject() - - s.name = "Volno" - s.place = "Volno" - s.teacher = "Volno" - s.substitute = "0" - s.number = number - s.start = start - s.end = end - s.free = true - - return s - } - - fun empty(): Subject { - val s = Subject() - - s.name = "err" - s.place = "error" - s.teacher = "error" - s.substitute = "0" - s.number = "0" - s.start = "00:00" - s.end = "00:00" - s.free = false - - return s - } - } - - override fun toString(): String { - return "subject ${this.name} at ${this.place} from ${this.start} to ${this.end}; free? ${this.free}" - } -} - -class Day { - var name: String = "" - var date: String = "" - var subjects: List = mutableListOf() -} \ No newline at end of file diff --git a/mobile/app/src/main/java/com/odweta/solon/Dialogs.kt b/mobile/app/src/main/java/com/odweta/solon/Dialogs.kt deleted file mode 100644 index 5bcda77..0000000 --- a/mobile/app/src/main/java/com/odweta/solon/Dialogs.kt +++ /dev/null @@ -1,48 +0,0 @@ -package com.odweta.solon - -import android.annotation.SuppressLint -import android.app.AlertDialog -import android.content.Context -import android.view.LayoutInflater -import androidx.core.content.ContextCompat - -class Dialogs { - @SuppressLint("InflateParams") - class LanguageChange(context: Context) : AlertDialog(context) { - init { - // Initialize your dialog properties - setTitle("Změnit jazyk") - setCancelable(true) - // Inflate the layout for the dialog - val view = LayoutInflater.from(context).inflate(R.layout.radio_group_language, null) - window?.setBackgroundDrawableResource(R.drawable.alert_dialog_background) - setView(view) - - // Set positive button (e.g., "OK" button) - setButton( - BUTTON_POSITIVE, - "OK" - ) { _, _ -> - // functionality here - dismiss() - } - - // Set negative button (e.g., "Cancel" button) - setButton( - BUTTON_NEGATIVE, - "Zrušit" - ) { _, _ -> - dismiss() - } - } - - override fun onStart() { - super.onStart() - - val okButton = getButton(BUTTON_POSITIVE) - okButton?.setTextColor(ContextCompat.getColor(context, R.color.white)) - val cancelButton = getButton(BUTTON_NEGATIVE) - cancelButton?.setTextColor(ContextCompat.getColor(context, R.color.white)) - } - } -} \ No newline at end of file diff --git a/mobile/app/src/main/java/com/odweta/solon/Launch.kt b/mobile/app/src/main/java/com/odweta/solon/Launch.kt new file mode 100644 index 0000000..810520a --- /dev/null +++ b/mobile/app/src/main/java/com/odweta/solon/Launch.kt @@ -0,0 +1,294 @@ +package com.odweta.solon + +import android.app.Activity +import android.content.Context +import android.content.Intent +import android.widget.Toast +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.delay +import org.json.JSONObject +import kotlin.math.cos + +private var week: List = mutableListOf() +private var toastShowing: Boolean = false +private var toastShown: Boolean = false +private var toast2Shown: Boolean = false + +private lateinit var coscope_: CoroutineScope + +private fun setOnInternetAvailListener(ctx: Context, coscope: CoroutineScope) { + coscope.launch { + while (true) { + if (Util.internetAvail(ctx) && !internetAvail) { + internetAvail = Util.internetAvail(ctx) + coscope.launch { + fetchNewData(ctx, coscope) + } + } else if (!internetAvail) { + internetAvail = Util.internetAvail(ctx) + toolbarText.value = "Bez připojení k internetu." + } else { + internetAvail = Util.internetAvail(ctx) + } + delay(1000) // Check for internet availability every second + } + } +} + +private fun fetchNewData(ctx: Context, coscope: CoroutineScope) { + coscope.launch { + done = false + + // variables for the loading animation + val loadingArray: Array = arrayOf( + "Načítání nových dat", + "Načítání nových dat.", + "Načítání nových dat..", + "Načítání nových dat..." + ) + val delayTime: Long = 300 // delay in ms + + // show a loading animation + while (!done && Util.internetAvail(ctx)) { + for (text in loadingArray) { + toolbarText.value = text + delay(delayTime) + } + + for (text in loadingArray.reversedArray().slice(1.. = mutableListOf() - private var toastShowing: Boolean = false - private var toastShown: Boolean = false - private var toast2Shown: Boolean = false - - // @section COMPANION - companion object { - private var intfc: MainActivityListener? = null - - fun setListener(context: Context) { - if (context is MainActivityListener) { - intfc = context - } - } - - fun callOnSignIn(view: View, wantDelete: Boolean, dialog: Dialog?) { - intfc?.onSignIn(view, wantDelete, dialog) - } - - fun callLaunchPhase1() { - intfc?.launchPhase1() - } - } - - - // @section LISTENERS +class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - // set variables - Vars.fileDir = applicationContext.filesDir - Vars.width = Util.getDisplayWidth(this) - Vars.height = Util.getDisplayHeight(this) + makeStatusBarBlack(window) - // start the app (coroutine because splashscreen) - lifecycleScope.launch { - launch() - } - } - - - - - // @section SIGN_IN - override fun onSignIn(view: View, wantDelete: Boolean, dialog: Dialog?) { - val acc = Account( - view.findViewById(R.id.usernameField).text.toString(), - view.findViewById(R.id.passwordField).text.toString(), - 0 - ) - - var checked = false - lifecycleScope.launch { - val btn = view.findViewById