Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
Tiebe committed Feb 9, 2024
2 parents c968426 + 3dad998 commit 6e7454f
Show file tree
Hide file tree
Showing 26 changed files with 707 additions and 19 deletions.
1 change: 1 addition & 0 deletions androidApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,5 @@ dependencies {
implementation(libs.compose.material)

implementation(libs.decompose.core)
implementation(libs.play.services.wearable)
}
14 changes: 14 additions & 0 deletions androidApp/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@
</intent-filter>
</activity>

<activity
android:name="nl.tiebe.otarium.androidApp.WearLoginActivity"
android:exported="true"
android:theme="@style/Theme.AppCompat.NoActionBar" >
</activity>

<meta-data
android:name="google_analytics_adid_collection_enabled"
android:value="false" />
Expand All @@ -53,6 +59,14 @@
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>

<service android:name=".WearListener"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
<data android:scheme="wear" android:host="*" android:pathPrefix="/wear_login" />
</intent-filter>
</service>
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package nl.tiebe.otarium.androidApp

import android.content.Intent
import com.google.android.gms.wearable.MessageEvent
import com.google.android.gms.wearable.WearableListenerService

class WearListener : WearableListenerService() {
override fun onMessageReceived(messageEvent: MessageEvent) {
val intent = Intent(applicationContext, WearLoginActivity::class.java)
intent.putExtra("uri", messageEvent.data)
intent.putExtra("node", messageEvent.sourceNodeId)
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

startActivity(intent)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package nl.tiebe.otarium.androidApp

import android.annotation.SuppressLint
import android.os.Bundle
import android.view.ViewGroup
import android.webkit.WebResourceRequest
import android.webkit.WebResourceResponse
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.activity.addCallback
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Modifier
import androidx.compose.ui.viewinterop.AndroidView
import com.google.android.gms.wearable.Wearable
import nl.tiebe.otarium.ui.login.getActivity
import nl.tiebe.otarium.utils.ui.Android

class WearLoginActivity : AppCompatActivity() {
@SuppressLint("SetJavaScriptEnabled")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

val onBackDispatcher = onBackPressedDispatcher

Android.context = this
Android.window = window

val url = intent.extras?.getByteArray("uri")!!.decodeToString()
val node = intent.extras?.getString("node")!!

setContent {
AndroidView(factory = {
val webViewClient: WebViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(
view: WebView,
webResourceRequest: WebResourceRequest
): Boolean {
val checkUrl = webResourceRequest.url.toString()

if (checkUrl.startsWith("m6loapp://oauth2redirect")) {
println("sending....")
Wearable.getMessageClient(applicationContext).sendMessage(node, "/login_completed", checkUrl.toByteArray())
return true
}

return false
}

override fun shouldInterceptRequest(
view: WebView?,
request: WebResourceRequest?
): WebResourceResponse? {
if (request?.url.toString().contains("playconsolelogin")) {
Wearable.getMessageClient(applicationContext).sendMessage(node, "/login_bypass", null)
}
return super.shouldInterceptRequest(view, request)
}
}

val webView = WebView(it).apply {
settings.javaScriptEnabled = true
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
this.webViewClient = webViewClient
loadUrl(url)
}

onBackDispatcher.addCallback {
if (webView.canGoBack()) webView.goBack()
else getActivity(it)?.finishAfterTransition()
}

webView
}, update = {
it.loadUrl(url)
}, modifier = Modifier.fillMaxSize())
}

}

}
2 changes: 2 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
@Suppress("DSL_SCOPE_VIOLATION")
plugins {
alias(libs.plugins.complete.kotlin)
alias(libs.plugins.androidApplication) apply false
alias(libs.plugins.kotlinAndroid) apply false
}

buildscript {
Expand Down
32 changes: 28 additions & 4 deletions libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ android_sdk-compile = "34"

ios_target = "11.0"

magister = "1.1.17"
magister = "1.2.0"

work-android = "2.9.0"

Expand All @@ -16,10 +16,10 @@ gradle = "8.2.2"
appcompat = "1.6.1"
material = "1.11.0"
compose = "1.5.11"
compose-android = "1.6.0"
compose-android = "1.6.1"
compose-compiler = "1.5.7"
compose-activity = "1.8.2"
material3 = "1.2.0-rc01"
material3 = "1.2.0"
ktor = "2.3.7"
decompose = "2.2.0-compose-experimental-alpha05"
moko = "0.24.0-alpha-2"
Expand All @@ -34,7 +34,19 @@ colormath = "3.4.0"

kotlin-datetime = "0.5.0"

# --- IDEA ---
# Make navigation between agenda and grades screen like spotify. That means first page is agenda, second page is grades. You can only swipe to exit on the agenda page.

skiko = "0.7.85.4"
agp = "8.2.2"
kotlin190 = "1.9.0"
play-services-wearable = "18.1.0"
wear-compose-bom = "2024.02.00"
compose-material = "1.3.0"
compose-material3 = "1.0.0-alpha17"
compose-foundation = "1.3.0"
core-splashscreen = "1.0.1"
wear-phone-interactions = "1.0.1"

[libraries]
compose-activity = { group = "androidx.activity", name = "activity-compose", version.ref = "compose-activity" }
Expand Down Expand Up @@ -82,9 +94,21 @@ guava-coroutines = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines
androidx-work = { group = "androidx.work", name = "work-runtime-ktx", version.ref = "work-android" }

skiko = { group = "org.jetbrains.skiko", name = "skiko", version.ref = "skiko" }
play-services-wearable = { group = "com.google.android.gms", name = "play-services-wearable", version.ref = "play-services-wearable" }
wear-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "wear-compose-bom" }
wear-tooling-preview = { group = "androidx.wear", name = "wear-tooling-preview" }
ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-wear-compose-compose-material = { group = "androidx.wear.compose", name = "compose-material", version.ref = "compose-material" }
androidx-wear-compose-compose-material3 = { group = "androidx.wear.compose", name = "compose-material3", version.ref = "compose-material3" }
compose-foundation = { group = "androidx.wear.compose", name = "compose-foundation", version.ref = "compose-foundation" }
core-splashscreen = { group = "androidx.core", name = "core-splashscreen", version.ref = "core-splashscreen" }
androidx-wear-phone-interactions = { group = "androidx.wear", name = "wear-phone-interactions", version.ref = "wear-phone-interactions" }

[plugins]
mokoresources = { id = "dev.icerock.mobile.multiplatform-resources", version.ref = "moko" }
complete_kotlin = { id = "com.louiscad.complete-kotlin", version.ref = "complete-kotlin" }
compose = { id = "org.jetbrains.compose", version.ref = "compose" }
buildkonfig = { id = "com.codingfeline.buildkonfig", version.ref = "buildkonfig" }
buildkonfig = { id = "com.codingfeline.buildkonfig", version.ref = "buildkonfig" }
androidApplication = { id = "com.android.application", version.ref = "agp" }
kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin190" }
1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ rootProject.name = "Otarium"

include(":androidApp")
include(":shared")
include(":wearApp")
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import androidx.core.text.HtmlCompat

@Composable
actual fun HtmlView(html: String, textColor: Int, linkColor: Int, backgroundColor: Int, maxLines: Int) {
val color = if (textColor == 0) {
val color = if (textColor == -1) {
LocalTextStyle.current.color.takeOrElse { LocalContentColor.current }.toArgb()
} else textColor

Expand All @@ -25,7 +25,7 @@ actual fun HtmlView(html: String, textColor: Int, linkColor: Int, backgroundColo

setTextColor(color)
setLinkTextColor(linkColor)
setBackgroundColor(backgroundColor)
if (backgroundColor != -1) setBackgroundColor(backgroundColor)

if (maxLines > 0) {
setMaxLines(maxLines)
Expand Down
2 changes: 1 addition & 1 deletion shared/src/commonMain/kotlin/nl/tiebe/otarium/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,6 @@ internal val LocalComponentContext: ProvidableCompositionLocal<ComponentContext>
staticCompositionLocalOf { error("Root component context was not provided") }

@Composable
internal fun ProvideComponentContext(componentContext: ComponentContext, content: @Composable () -> Unit) {
fun ProvideComponentContext(componentContext: ComponentContext, content: @Composable () -> Unit) {
CompositionLocalProvider(LocalComponentContext provides componentContext, content = content)
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import androidx.compose.material.pullrefresh.rememberPullRefreshState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import com.arkivanov.decompose.extensions.compose.jetbrains.subscribeAsState
Expand All @@ -26,7 +28,12 @@ internal fun RecentGradesScreen(component: RecentGradesComponent) {
val grades = component.grades.subscribeAsState().value

val scrollState = rememberScrollState()
val reachedEnd = derivedStateOf { scrollState.value >= (scrollState.maxValue * 0.5).toInt() }
val reachedEnd by remember { derivedStateOf { scrollState.value >= (scrollState.maxValue * 0.5).toInt() } }

LaunchedEffect(reachedEnd) {
if (!component.refreshState.value)
component.loadNextGrades()
}

Column(
modifier = Modifier
Expand All @@ -36,13 +43,6 @@ internal fun RecentGradesScreen(component: RecentGradesComponent) {
grades.forEach {
GradeItem(component = component, grade = it)
}

if (reachedEnd.value) {
LaunchedEffect(Unit) {
if (!component.refreshState.value)
component.loadNextGrades()
}
}
}

PullRefreshIndicator(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import androidx.compose.ui.graphics.toArgb
@Composable
expect fun HtmlView(
html: String,
textColor: Int = 0,
textColor: Int = -1,
linkColor: Int = Color(83, 155, 245).toArgb(),
backgroundColor: Int,
maxLines: Int = 0
Expand Down
10 changes: 7 additions & 3 deletions shared/src/commonMain/kotlin/nl/tiebe/otarium/utils/Utils.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package nl.tiebe.otarium.utils

import androidx.compose.ui.graphics.ImageBitmap
import kotlinx.datetime.*
import kotlinx.datetime.Instant
import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toInstant
import kotlinx.datetime.toLocalDateTime
import nl.tiebe.otarium.Data
import nl.tiebe.otarium.magister.GradeWithGradeInfo
import nl.tiebe.otarium.magister.MagisterAccount
Expand Down Expand Up @@ -54,10 +58,10 @@ fun Instant.toFormattedStringDate(): String {
return "${dateTime.dayOfMonth.toFormattedString()}-${dateTime.monthNumber.toFormattedString()}-${dateTime.year.toFormattedString()}"
}

fun Instant.toFormattedStringTime(): String {
fun Instant.toFormattedStringTime(seconds: Boolean = true): String {
val dateTime = this.toLocalDateTime(TimeZone.of("Europe/Amsterdam"))

return "${dateTime.hour.toFormattedString()}:${dateTime.minute.toFormattedString()}:${dateTime.second.toFormattedString()}"
return "${dateTime.hour.toFormattedString()}:${dateTime.minute.toFormattedString()}" + if (seconds) ":${dateTime.second.toFormattedString()}" else ""
}

fun Int.toFormattedString(): String {
Expand Down
1 change: 1 addition & 0 deletions wearApp/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
71 changes: 71 additions & 0 deletions wearApp/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
plugins {
id("com.android.application")
kotlin("android")
id("kotlin-parcelize")
id("kotlinx-serialization")
}

android {
namespace = "nl.tiebe.otarium.wear"
compileSdk = 34

defaultConfig {
applicationId = "nl.tiebe.otarium"
minSdk = 30
targetSdk = libs.versions.android.sdk.compile.get().toInt()
versionCode = libs.versions.app.version.code.get().toInt()
versionName = libs.versions.app.version.string.get()
vectorDrawables {
useSupportLibrary = true
}

}

buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = "11"
}
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = libs.versions.compose.compiler.get()
}
}

dependencies {
implementation(project(":shared"))

implementation(libs.play.services.wearable)
implementation(platform(libs.wear.compose.bom))
implementation(libs.compose.ui)
// implementation(libs.wear.tooling.preview)
implementation(libs.androidx.wear.compose.compose.material)
implementation(libs.androidx.wear.compose.compose.material3)
implementation(libs.compose.foundation)
implementation(libs.compose.activity)
implementation(libs.core.splashscreen)
implementation(libs.androidx.wear.phone.interactions)
debugImplementation(libs.ui.tooling)
debugImplementation(libs.ui.test.manifest)

implementation(libs.kotlin.datetime)

implementation(libs.decompose.core)
implementation(libs.decompose.compose)

api(libs.moko.resources.core)
implementation(libs.magister.api)
}
Loading

0 comments on commit 6e7454f

Please sign in to comment.