From 72e596dde26af3649e94facf25b024b1c28ba86d Mon Sep 17 00:00:00 2001 From: Carlos Mota Date: Sun, 2 Feb 2025 18:20:39 +0000 Subject: [PATCH 1/6] Updated Chapter 12 Starter Project --- 12-networking/projects/starter/.gitignore | 3 +- 12-networking/projects/starter/.idea/.name | 1 - .../.idea/artifacts/desktopApp_jvm.xml | 4 +- .../.idea/artifacts/shared_dto_jvm.xml | 4 +- .../projects/starter/.idea/compiler.xml | 6 - .../.idea/deploymentTargetDropDown.xml | 10 -- .../projects/starter/.idea/gradle.xml | 2 +- .../projects/starter/.idea/kotlinc.xml | 2 +- 12-networking/projects/starter/.idea/misc.xml | 7 +- .../starter/androidApp/build.gradle.kts | 12 +- .../com/kodeco/learn/KodecoApplication.kt | 2 +- .../kodeco/learn/components/ImagePreview.kt | 2 +- .../java/com/kodeco/learn/ui/MainActivity.kt | 2 +- .../learn/ui/bookmark/BookmarkContent.kt | 10 +- .../learn/ui/bookmark/BookmarkViewModel.kt | 2 +- .../kodeco/learn/ui/common/EmptyContent.kt | 2 +- .../kodeco/learn/ui/common/EntryContent.kt | 12 +- .../com/kodeco/learn/ui/home/FeedViewModel.kt | 3 +- .../com/kodeco/learn/ui/home/HomeContent.kt | 8 +- .../kodeco/learn/ui/home/HomeSheetContent.kt | 12 +- .../kodeco/learn/ui/latest/LatestContent.kt | 2 +- .../learn/ui/main/BottomNavigationScreens.kt | 2 +- .../com/kodeco/learn/ui/main/MainBottomBar.kt | 2 +- .../com/kodeco/learn/ui/main/MainContent.kt | 10 +- .../com/kodeco/learn/ui/main/MainScreen.kt | 10 +- .../com/kodeco/learn/ui/main/MainTopAppBar.kt | 2 +- .../kodeco/learn/ui/search/SearchContent.kt | 8 +- .../java/com/kodeco/learn/ui/theme/Color.kt | 2 +- .../java/com/kodeco/learn/ui/theme/Shape.kt | 2 +- .../java/com/kodeco/learn/ui/theme/Theme.kt | 47 ++++---- .../java/com/kodeco/learn/ui/theme/Type.kt | 36 +++++- .../main/java/com/kodeco/learn/utils/Utils.kt | 6 +- .../projects/starter/build.gradle.kts | 7 +- .../starter/desktopApp/build.gradle.kts | 50 +++++--- .../drawable}/ic_bookmarks.xml | 0 .../composeResources/drawable}/ic_brand.xml | 0 .../composeResources/drawable}/ic_home.xml | 0 .../composeResources/drawable}/ic_latest.xml | 0 .../composeResources/drawable}/ic_more.xml | 0 .../composeResources/drawable}/ic_search.xml | 0 .../composeResources}/font/opensans_bold.ttf | Bin .../font/opensans_extrabold.ttf | Bin .../composeResources}/font/opensans_light.ttf | Bin .../font/opensans_regular.ttf | Bin .../font/opensans_semibold.ttf | Bin .../composeResources/values/strings.xml | 36 ++++++ .../jvmMain/kotlin/com/kodeco/learn/Main.kt | 13 ++- .../kodeco/learn/components/ImagePreview.kt | 18 +-- .../learn/ui/bookmark/BookmarkContent.kt | 2 +- .../learn/ui/bookmark/BookmarkViewModel.kt | 6 +- .../kodeco/learn/ui/common/EmptyContent.kt | 2 +- .../kodeco/learn/ui/common/EntryContent.kt | 19 ++-- .../com/kodeco/learn/ui/home/FeedViewModel.kt | 5 +- .../com/kodeco/learn/ui/home/HomeContent.kt | 2 +- .../kodeco/learn/ui/home/HomeSheetContent.kt | 13 ++- .../kodeco/learn/ui/latest/LatestContent.kt | 2 +- .../learn/ui/main/BottomNavigationScreens.kt | 41 ++++--- .../com/kodeco/learn/ui/main/MainBottomBar.kt | 107 ------------------ .../com/kodeco/learn/ui/main/MainContent.kt | 59 +++++----- .../com/kodeco/learn/ui/main/MainScreen.kt | 67 ++++++----- .../com/kodeco/learn/ui/main/MainTopAppBar.kt | 10 +- .../kodeco/learn/ui/search/SearchContent.kt | 8 +- .../kotlin/com/kodeco/learn/ui/theme/Color.kt | 2 +- .../kotlin/com/kodeco/learn/ui/theme/Shape.kt | 2 +- .../kotlin/com/kodeco/learn/ui/theme/Theme.kt | 4 +- .../kotlin/com/kodeco/learn/ui/theme/Type.kt | 73 +++++++++--- .../kotlin/com/kodeco/learn/utils/Utils.kt | 6 +- .../projects/starter/gradle.properties | 1 - .../starter/gradle/libs.versions.toml | 40 +++---- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../starter/iosApp/iosApp/BookmarkView.swift | 2 +- .../starter/iosApp/iosApp/ContentView.swift | 2 +- .../starter/iosApp/iosApp/HomeView.swift | 2 +- .../iosApp/iosApp/KodecoEntryViewModel.swift | 2 +- .../starter/iosApp/iosApp/LatestView.swift | 2 +- .../iosApp/iosApp/MainToolbarContent.swift | 2 +- .../starter/iosApp/iosApp/SearchView.swift | 2 +- .../iosApp/iosApp/common/KodecoEntryRow.swift | 3 +- .../iosApp/extensions/BookmarkClient.swift | 2 +- .../iosApp/iosApp/extensions/FeedClient.swift | 3 +- .../starter/iosApp/iosApp/iOSApp.swift | 2 +- .../starter/iosApp/iosApp/utils/Actions.swift | 2 +- .../starter/iosApp/iosApp/utils/Utils.swift | 2 +- .../projects/starter/settings.gradle.kts | 2 +- .../starter/shared-dto/build.gradle.kts | 86 ++++++++------ .../learn/platform/Parcelable.android.kt | 4 +- .../com/kodeco/learn/data/KodecoSerializer.kt | 4 +- .../learn/data/model/GravatarContent.kt | 2 +- .../kodeco/learn/data/model/KodecoContent.kt | 2 +- .../kodeco/learn/data/model/KodecoEntry.kt | 4 +- .../learn/platform/Parcelable.common.kt | 2 +- .../kodeco/learn/platform/Parcelable.ios.kt | 2 +- ...arcelable.desktop.kt => Parcelable.jvm.kt} | 2 +- .../projects/starter/shared/build.gradle.kts | 81 ++++++------- .../kodeco/learn/platform/Database.android.kt | 2 +- .../kodeco/learn/platform/Logger.android.kt | 2 +- .../com/kodeco/learn/platform/Test.android.kt | 2 +- .../kotlin/com/kodeco/learn/ServiceLocator.kt | 2 +- .../com/kodeco/learn/domain/GetFeedData.kt | 2 +- .../kodeco/learn/domain/cb/BookmarkData.kt | 2 +- .../com/kodeco/learn/domain/cb/FeedData.kt | 2 +- .../kodeco/learn/domain/dao/KodecoEntryDAO.kt | 2 +- .../kodeco/learn/platform/Database.common.kt | 2 +- .../kodeco/learn/platform/Logger.common.kt | 2 +- .../com/kodeco/learn/platform/Test.common.kt | 2 +- .../learn/presentation/BookmarkPresenter.kt | 2 +- .../learn/presentation/FeedPresenter.kt | 51 ++++++++- .../commonTest/kotlin/SerializationTests.kt | 2 +- .../com/kodeco/learn/platform/Database.ios.kt | 2 +- .../com/kodeco/learn/platform/Logger.ios.kt | 2 +- .../com/kodeco/learn/platform/Test.ios.kt | 2 +- .../kodeco/learn/platform/Database.jvm.kt} | 2 +- .../com/kodeco/learn/platform/Logger.jvm.kt} | 2 +- .../com/kodeco/learn/platform/Test.jvm.kt} | 2 +- 114 files changed, 630 insertions(+), 510 deletions(-) delete mode 100644 12-networking/projects/starter/.idea/.name delete mode 100644 12-networking/projects/starter/.idea/compiler.xml delete mode 100644 12-networking/projects/starter/.idea/deploymentTargetDropDown.xml rename 12-networking/projects/starter/desktopApp/src/{jvmMain/resources/images => commonMain/composeResources/drawable}/ic_bookmarks.xml (100%) rename 12-networking/projects/starter/desktopApp/src/{jvmMain/resources/images => commonMain/composeResources/drawable}/ic_brand.xml (100%) rename 12-networking/projects/starter/desktopApp/src/{jvmMain/resources/images => commonMain/composeResources/drawable}/ic_home.xml (100%) rename 12-networking/projects/starter/desktopApp/src/{jvmMain/resources/images => commonMain/composeResources/drawable}/ic_latest.xml (100%) rename 12-networking/projects/starter/desktopApp/src/{jvmMain/resources/images => commonMain/composeResources/drawable}/ic_more.xml (100%) rename 12-networking/projects/starter/desktopApp/src/{jvmMain/resources/images => commonMain/composeResources/drawable}/ic_search.xml (100%) rename 12-networking/projects/starter/desktopApp/src/{jvmMain/resources => commonMain/composeResources}/font/opensans_bold.ttf (100%) rename 12-networking/projects/starter/desktopApp/src/{jvmMain/resources => commonMain/composeResources}/font/opensans_extrabold.ttf (100%) rename 12-networking/projects/starter/desktopApp/src/{jvmMain/resources => commonMain/composeResources}/font/opensans_light.ttf (100%) rename 12-networking/projects/starter/desktopApp/src/{jvmMain/resources => commonMain/composeResources}/font/opensans_regular.ttf (100%) rename 12-networking/projects/starter/desktopApp/src/{jvmMain/resources => commonMain/composeResources}/font/opensans_semibold.ttf (100%) create mode 100644 12-networking/projects/starter/desktopApp/src/commonMain/composeResources/values/strings.xml delete mode 100644 12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainBottomBar.kt rename 12-networking/projects/starter/shared-dto/src/jvmMain/kotlin/com/kodeco/learn/platform/{Parcelable.desktop.kt => Parcelable.jvm.kt} (98%) rename 12-networking/projects/starter/shared/src/{desktopMain/kotlin/com/kodeco/learn/platform/Database.desktop.kt => jvmMain/kotlin/com/kodeco/learn/platform/Database.jvm.kt} (98%) rename 12-networking/projects/starter/shared/src/{desktopMain/kotlin/com/kodeco/learn/platform/Logger.desktop.kt => jvmMain/kotlin/com/kodeco/learn/platform/Logger.jvm.kt} (98%) rename 12-networking/projects/starter/shared/src/{desktopMain/kotlin/com/kodeco/learn/platform/Test.desktop.kt => jvmMain/kotlin/com/kodeco/learn/platform/Test.jvm.kt} (98%) diff --git a/12-networking/projects/starter/.gitignore b/12-networking/projects/starter/.gitignore index b1bb87f1..90d16852 100644 --- a/12-networking/projects/starter/.gitignore +++ b/12-networking/projects/starter/.gitignore @@ -15,8 +15,9 @@ bin/ gen/ out/ -# Gradle files +# Project files .gradle/ +.kotlin/ build/ androidApp/build desktopApp/build diff --git a/12-networking/projects/starter/.idea/.name b/12-networking/projects/starter/.idea/.name deleted file mode 100644 index 2eefc69e..00000000 --- a/12-networking/projects/starter/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -learn \ No newline at end of file diff --git a/12-networking/projects/starter/.idea/artifacts/desktopApp_jvm.xml b/12-networking/projects/starter/.idea/artifacts/desktopApp_jvm.xml index 3351a9e4..c6a344f7 100644 --- a/12-networking/projects/starter/.idea/artifacts/desktopApp_jvm.xml +++ b/12-networking/projects/starter/.idea/artifacts/desktopApp_jvm.xml @@ -1,8 +1,6 @@ $PROJECT_DIR$/desktopApp/build/libs - - - + \ No newline at end of file diff --git a/12-networking/projects/starter/.idea/artifacts/shared_dto_jvm.xml b/12-networking/projects/starter/.idea/artifacts/shared_dto_jvm.xml index e9ca92e9..0d4cbc2a 100644 --- a/12-networking/projects/starter/.idea/artifacts/shared_dto_jvm.xml +++ b/12-networking/projects/starter/.idea/artifacts/shared_dto_jvm.xml @@ -1,8 +1,6 @@ $PROJECT_DIR$/shared-dto/build/libs - - - + \ No newline at end of file diff --git a/12-networking/projects/starter/.idea/compiler.xml b/12-networking/projects/starter/.idea/compiler.xml deleted file mode 100644 index b589d56e..00000000 --- a/12-networking/projects/starter/.idea/compiler.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/12-networking/projects/starter/.idea/deploymentTargetDropDown.xml b/12-networking/projects/starter/.idea/deploymentTargetDropDown.xml deleted file mode 100644 index b1d56a76..00000000 --- a/12-networking/projects/starter/.idea/deploymentTargetDropDown.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/12-networking/projects/starter/.idea/gradle.xml b/12-networking/projects/starter/.idea/gradle.xml index e18ef036..26829bc4 100644 --- a/12-networking/projects/starter/.idea/gradle.xml +++ b/12-networking/projects/starter/.idea/gradle.xml @@ -4,6 +4,7 @@ diff --git a/12-networking/projects/starter/.idea/kotlinc.xml b/12-networking/projects/starter/.idea/kotlinc.xml index f8467b45..bb449370 100644 --- a/12-networking/projects/starter/.idea/kotlinc.xml +++ b/12-networking/projects/starter/.idea/kotlinc.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/12-networking/projects/starter/.idea/misc.xml b/12-networking/projects/starter/.idea/misc.xml index adb8ae0f..b2c751a3 100644 --- a/12-networking/projects/starter/.idea/misc.xml +++ b/12-networking/projects/starter/.idea/misc.xml @@ -1,4 +1,9 @@ - + + + + + \ No newline at end of file diff --git a/12-networking/projects/starter/androidApp/build.gradle.kts b/12-networking/projects/starter/androidApp/build.gradle.kts index 820caca5..9b6d2be3 100644 --- a/12-networking/projects/starter/androidApp/build.gradle.kts +++ b/12-networking/projects/starter/androidApp/build.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -35,6 +35,8 @@ plugins { id("com.android.application") kotlin("android") + + alias(libs.plugins.jetbrains.compose.compiler) } dependencies { @@ -63,8 +65,8 @@ android { applicationId = "com.kodeco.learn" minSdk = libs.versions.android.sdk.min.get().toInt() targetSdk = libs.versions.android.sdk.target.get().toInt() - versionCode = 2 - versionName = "2.0" + versionCode = 3 + versionName = "3.0" } buildTypes { @@ -86,10 +88,6 @@ android { jvmTarget = "17" } - composeOptions { - kotlinCompilerExtensionVersion = libs.versions.android.compose.compiler.get() - } - packaging { resources { excludes += "/META-INF/{AL2.0,LGPL2.1}" diff --git a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/KodecoApplication.kt b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/KodecoApplication.kt index 1dbfd1c6..bb5174e2 100644 --- a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/KodecoApplication.kt +++ b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/KodecoApplication.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/components/ImagePreview.kt b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/components/ImagePreview.kt index 9a33e6c5..b404d47e 100644 --- a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/components/ImagePreview.kt +++ b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/components/ImagePreview.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/MainActivity.kt b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/MainActivity.kt index 4d31c99a..7d616ec5 100644 --- a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/MainActivity.kt +++ b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/MainActivity.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/bookmark/BookmarkContent.kt b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/bookmark/BookmarkContent.kt index fb81f218..205fd1f1 100644 --- a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/bookmark/BookmarkContent.kt +++ b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/bookmark/BookmarkContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -37,8 +37,8 @@ package com.kodeco.learn.ui.bookmark import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.material.BottomSheetScaffoldState -import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.State @@ -53,7 +53,7 @@ import kotlinx.coroutines.CoroutineScope private const val TAG = "BookmarkContent" -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun BookmarkContent( selected: MutableState, @@ -80,7 +80,7 @@ fun BookmarkContent( } } -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun AddBookmarks( selected: MutableState, diff --git a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/bookmark/BookmarkViewModel.kt b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/bookmark/BookmarkViewModel.kt index b1b885a7..75b939f8 100644 --- a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/bookmark/BookmarkViewModel.kt +++ b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/bookmark/BookmarkViewModel.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/common/EmptyContent.kt b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/common/EmptyContent.kt index bd221c2d..ba7b331f 100644 --- a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/common/EmptyContent.kt +++ b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/common/EmptyContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/common/EntryContent.kt b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/common/EntryContent.kt index 28ea5f76..5107a643 100644 --- a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/common/EntryContent.kt +++ b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/common/EntryContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -45,9 +45,9 @@ 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.BottomSheetScaffoldState -import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material3.Divider +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -69,7 +69,7 @@ import kotlinx.coroutines.launch private const val TAG = "EntryContent" -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun AddEntryContent( item: KodecoEntry, @@ -169,7 +169,7 @@ fun AddEntryContent( Spacer(modifier = Modifier.height(16.dp)) if (divider) { - Divider( + HorizontalDivider( modifier = Modifier.fillMaxWidth(), thickness = 1.dp ) diff --git a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/home/FeedViewModel.kt b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/home/FeedViewModel.kt index 1ea6f6af..9b4617a7 100644 --- a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/home/FeedViewModel.kt +++ b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/home/FeedViewModel.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -63,6 +63,7 @@ class FeedViewModel : ViewModel(), FeedData { fun fetchAllFeeds() { Logger.d(TAG, "fetchAllFeeds") + _items[PLATFORM.ALL] = presenter.allFeeds } fun fetchMyGravatar() { diff --git a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/home/HomeContent.kt b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/home/HomeContent.kt index 99dd0f0d..a1a30553 100644 --- a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/home/HomeContent.kt +++ b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/home/HomeContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -47,8 +47,8 @@ import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.BottomSheetScaffoldState -import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState @@ -69,7 +69,7 @@ import kotlinx.coroutines.CoroutineScope private const val TAG = "HomeContent" -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun HomeContent( selected: MutableState, diff --git a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/home/HomeSheetContent.kt b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/home/HomeSheetContent.kt index 88890b61..d4d1a53a 100644 --- a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/home/HomeSheetContent.kt +++ b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/home/HomeSheetContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -39,8 +39,8 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.material.BottomSheetScaffoldState -import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState @@ -55,7 +55,7 @@ import kotlinx.coroutines.launch private const val TAG = "HomeSheetContent" -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun HomeSheetContent( item: MutableState, @@ -76,7 +76,7 @@ fun HomeSheetContent( .fillMaxWidth() .clickable { coroutineScope.launch { - bottomSheetScaffoldState.bottomSheetState.collapse() + bottomSheetScaffoldState.bottomSheetState.hide() } onUpdateBookmark(item.value) @@ -102,7 +102,7 @@ fun HomeSheetContent( .fillMaxWidth() .clickable { coroutineScope.launch { - bottomSheetScaffoldState.bottomSheetState.collapse() + bottomSheetScaffoldState.bottomSheetState.hide() } onShareAsLink(item.value) diff --git a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/latest/LatestContent.kt b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/latest/LatestContent.kt index 32045322..382e52a5 100644 --- a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/latest/LatestContent.kt +++ b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/latest/LatestContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/main/BottomNavigationScreens.kt b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/main/BottomNavigationScreens.kt index 8e3f6ebf..1e97ea99 100644 --- a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/main/BottomNavigationScreens.kt +++ b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/main/BottomNavigationScreens.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/main/MainBottomBar.kt b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/main/MainBottomBar.kt index 94a16670..69c8dde6 100644 --- a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/main/MainBottomBar.kt +++ b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/main/MainBottomBar.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/main/MainContent.kt b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/main/MainContent.kt index ebecd8e2..da09e23f 100644 --- a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/main/MainContent.kt +++ b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/main/MainContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -35,8 +35,8 @@ package com.kodeco.learn.ui.main import androidx.compose.foundation.layout.Column -import androidx.compose.material.BottomSheetScaffoldState -import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.State @@ -54,7 +54,7 @@ import kotlinx.coroutines.CoroutineScope private val DEFAULT_SCREEN = BottomNavigationScreens.Home -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun MainContent( navController: NavHostController, @@ -79,7 +79,7 @@ fun MainContent( } } -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable private fun MainScreenNavigationConfigurations( navController: NavHostController, diff --git a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/main/MainScreen.kt b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/main/MainScreen.kt index 66964f83..4f17901a 100644 --- a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/main/MainScreen.kt +++ b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/main/MainScreen.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -37,9 +37,9 @@ package com.kodeco.learn.ui.main import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.BottomSheetScaffold -import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.rememberBottomSheetScaffoldState +import androidx.compose.material3.BottomSheetScaffold +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.rememberBottomSheetScaffoldState import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState @@ -58,7 +58,7 @@ import com.kodeco.learn.ui.home.HomeSheetContent private lateinit var selected: MutableState -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun MainScreen( profile: GravatarEntry?, diff --git a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/main/MainTopAppBar.kt b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/main/MainTopAppBar.kt index 5ed7977a..65e05449 100644 --- a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/main/MainTopAppBar.kt +++ b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/main/MainTopAppBar.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/search/SearchContent.kt b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/search/SearchContent.kt index f0685e21..137399c8 100644 --- a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/search/SearchContent.kt +++ b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/search/SearchContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,8 +38,8 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.material.BottomSheetScaffoldState -import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Surface @@ -63,7 +63,7 @@ import kotlinx.coroutines.CoroutineScope private const val TAG = "SearchContent" -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun SearchContent( selected: MutableState, diff --git a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/theme/Color.kt b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/theme/Color.kt index a594ad49..2e781c25 100644 --- a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/theme/Color.kt +++ b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/theme/Color.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/theme/Shape.kt b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/theme/Shape.kt index 8964a873..329ab7f5 100644 --- a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/theme/Shape.kt +++ b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/theme/Shape.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/theme/Theme.kt b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/theme/Theme.kt index 0fd73cb6..b59eedd4 100644 --- a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/theme/Theme.kt +++ b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/theme/Theme.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -35,6 +35,7 @@ package com.kodeco.learn.ui.theme import android.app.Activity +import android.os.Build import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.material3.MaterialTheme import androidx.compose.material3.darkColorScheme @@ -46,27 +47,28 @@ import androidx.compose.ui.platform.LocalView import androidx.core.view.WindowCompat private val DarkColorScheme = darkColorScheme( - primary = darkTextPrimary, - surface = darkBackground, - onSurfaceVariant = darkTextPrimary, - background = darkBackground, - secondaryContainer = darkSecondaryContainer, - onSecondaryContainer = darkBackground + primary = darkTextPrimary, + surface = darkBackground, + onSurfaceVariant = darkTextPrimary, + background = darkBackground, + secondaryContainer = darkSecondaryContainer, + onSecondaryContainer = darkBackground ) private val LightColorScheme = lightColorScheme( - primary = lightTextPrimary, - surface = lightBackground, - onSurfaceVariant = lightTextPrimary, - background = lightBackground, - secondaryContainer = lightSecondaryContainer, - onSecondaryContainer = lightBackground + primary = lightTextPrimary, + surface = lightBackground, + onSurfaceVariant = lightTextPrimary, + background = lightBackground, + secondaryContainer = lightSecondaryContainer, + onSecondaryContainer = lightBackground ) +@Suppress("DEPRECATION") @Composable fun KodecoTheme( - darkTheme: Boolean = isSystemInDarkTheme(), - content: @Composable () -> Unit + darkTheme: Boolean = isSystemInDarkTheme(), + content: @Composable () -> Unit ) { val colorScheme = when { darkTheme -> DarkColorScheme @@ -77,14 +79,21 @@ fun KodecoTheme( if (!view.isInEditMode) { SideEffect { val window = (view.context as Activity).window - window.statusBarColor = colorScheme.surface.toArgb() + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) { + window.decorView.setOnApplyWindowInsetsListener { view, insets -> + view.setBackgroundColor(colorScheme.surface.toArgb()) + insets + } + } else { + window.statusBarColor = colorScheme.surface.toArgb() + } WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !darkTheme } } MaterialTheme( - colorScheme = colorScheme, - typography = Typography, - content = content + colorScheme = colorScheme, + typography = Typography, + content = content ) } \ No newline at end of file diff --git a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/theme/Type.kt b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/theme/Type.kt index 5c500810..a5ef1f0b 100644 --- a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/theme/Type.kt +++ b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/theme/Type.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -90,5 +90,39 @@ val Typography = Typography( bodySmall = TextStyle( fontFamily = OpenSansFontFamily, fontSize = fontSizeSmall + ), + + titleLarge = TextStyle( + fontFamily = OpenSansFontFamily, + fontWeight = FontWeight.Normal, + fontSize = fontSizeBig + ), + + titleMedium = TextStyle( + fontFamily = OpenSansFontFamily, + fontWeight = FontWeight.Bold, + fontSize = fontSizeSmall + ), + + titleSmall = TextStyle( + fontFamily = OpenSansFontFamily, + fontSize = fontSizeSmall + ), + + labelLarge = TextStyle( + fontFamily = OpenSansFontFamily, + fontWeight = FontWeight.Normal, + fontSize = fontSizeBig + ), + + labelMedium = TextStyle( + fontFamily = OpenSansFontFamily, + fontWeight = FontWeight.Bold, + fontSize = fontSizeSmall + ), + + labelSmall = TextStyle( + fontFamily = OpenSansFontFamily, + fontSize = fontSizeSmall ) ) \ No newline at end of file diff --git a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/utils/Utils.kt b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/utils/Utils.kt index ce66defb..b0cec1fc 100644 --- a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/utils/Utils.kt +++ b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/utils/Utils.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -36,7 +36,7 @@ package com.kodeco.learn.utils import android.annotation.SuppressLint import com.kodeco.learn.platform.Logger -import kotlinx.datetime.toInstant +import kotlinx.datetime.Instant import java.text.SimpleDateFormat import java.util.* @@ -47,7 +47,7 @@ private val simpleDateFormat = SimpleDateFormat("yyyy/MM/dd", Locale.getDefault( fun converterIso8601ToReadableDate(date: String): String { return try { - val instant = date.toInstant() + val instant = Instant.parse(date) val millis = Date(instant.toEpochMilliseconds()) return simpleDateFormat.format(millis) } catch (e: Exception) { diff --git a/12-networking/projects/starter/build.gradle.kts b/12-networking/projects/starter/build.gradle.kts index f9602113..8d1115ba 100644 --- a/12-networking/projects/starter/build.gradle.kts +++ b/12-networking/projects/starter/build.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,15 +32,14 @@ * THE SOFTWARE. */ -// Top-level build file where you can add configuration options common to all sub-projects/modules. -@Suppress("DSL_SCOPE_VIOLATION") plugins { alias(libs.plugins.android.application) apply false alias(libs.plugins.android.library) apply false + alias(libs.plugins.jetbrains.compose.compiler) apply false alias(libs.plugins.jetbrains.kotlin) apply false alias(libs.plugins.jetbrains.kotlin.multiplatform) apply false - alias(libs.plugins.jetbrains.kotlin.parcelize) apply false alias(libs.plugins.jetbrains.kotlin.serialization) apply false + alias(libs.plugins.jetbrains.kotlin.parcelize) apply false alias(libs.plugins.cash.sqldelight) apply false } diff --git a/12-networking/projects/starter/desktopApp/build.gradle.kts b/12-networking/projects/starter/desktopApp/build.gradle.kts index 1515c5ed..40b47c25 100644 --- a/12-networking/projects/starter/desktopApp/build.gradle.kts +++ b/12-networking/projects/starter/desktopApp/build.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -33,41 +33,50 @@ */ import org.jetbrains.compose.desktop.application.dsl.TargetFormat +import org.jetbrains.kotlin.gradle.dsl.JvmTarget plugins { alias(libs.plugins.jetbrains.kotlin.multiplatform) + alias(libs.plugins.jetbrains.compose) + alias(libs.plugins.jetbrains.compose.compiler) } kotlin { jvm { compilations.all { - kotlinOptions.jvmTarget = "17" + compileTaskProvider.configure { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_17) + } + } } } sourceSets { - getByName("jvmMain") { - dependencies { - implementation(project(":shared")) + commonMain.dependencies { + implementation(compose.components.resources) + } - implementation(compose.desktop.currentOs) + jvmMain.dependencies { + implementation(project(":shared")) - implementation(compose.foundation) - implementation(compose.runtime) - implementation(compose.foundation) - implementation(compose.material) - implementation(compose.material3) - implementation(compose.ui) + implementation(compose.desktop.currentOs) - implementation(libs.kotlinx.datetime) + implementation(compose.foundation) + implementation(compose.runtime) + implementation(compose.foundation) + implementation(compose.material) + implementation(compose.material3) + implementation(compose.material3AdaptiveNavigationSuite) + implementation(compose.ui) - implementation(libs.image.loader) + implementation(libs.kotlinx.datetime) - implementation(libs.precompose) - implementation(libs.precompose.viewmodel) - } + implementation(libs.image.loader) + + implementation(libs.jetbrains.compose.lifecycle) } } } @@ -79,7 +88,7 @@ compose.desktop { nativeDistributions { targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb) packageName = "learn" - packageVersion = "2.0.0" + packageVersion = "3.0.0" val resources = project.layout.projectDirectory.dir("src/jvmMain/resources") appResourcesRootDir.set(resources) @@ -98,4 +107,9 @@ compose.desktop { } } } +} + +compose.resources { + publicResClass = true + packageOfResClass = "com.kodeco.learn.resources" } \ No newline at end of file diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/resources/images/ic_bookmarks.xml b/12-networking/projects/starter/desktopApp/src/commonMain/composeResources/drawable/ic_bookmarks.xml similarity index 100% rename from 12-networking/projects/starter/desktopApp/src/jvmMain/resources/images/ic_bookmarks.xml rename to 12-networking/projects/starter/desktopApp/src/commonMain/composeResources/drawable/ic_bookmarks.xml diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/resources/images/ic_brand.xml b/12-networking/projects/starter/desktopApp/src/commonMain/composeResources/drawable/ic_brand.xml similarity index 100% rename from 12-networking/projects/starter/desktopApp/src/jvmMain/resources/images/ic_brand.xml rename to 12-networking/projects/starter/desktopApp/src/commonMain/composeResources/drawable/ic_brand.xml diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/resources/images/ic_home.xml b/12-networking/projects/starter/desktopApp/src/commonMain/composeResources/drawable/ic_home.xml similarity index 100% rename from 12-networking/projects/starter/desktopApp/src/jvmMain/resources/images/ic_home.xml rename to 12-networking/projects/starter/desktopApp/src/commonMain/composeResources/drawable/ic_home.xml diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/resources/images/ic_latest.xml b/12-networking/projects/starter/desktopApp/src/commonMain/composeResources/drawable/ic_latest.xml similarity index 100% rename from 12-networking/projects/starter/desktopApp/src/jvmMain/resources/images/ic_latest.xml rename to 12-networking/projects/starter/desktopApp/src/commonMain/composeResources/drawable/ic_latest.xml diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/resources/images/ic_more.xml b/12-networking/projects/starter/desktopApp/src/commonMain/composeResources/drawable/ic_more.xml similarity index 100% rename from 12-networking/projects/starter/desktopApp/src/jvmMain/resources/images/ic_more.xml rename to 12-networking/projects/starter/desktopApp/src/commonMain/composeResources/drawable/ic_more.xml diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/resources/images/ic_search.xml b/12-networking/projects/starter/desktopApp/src/commonMain/composeResources/drawable/ic_search.xml similarity index 100% rename from 12-networking/projects/starter/desktopApp/src/jvmMain/resources/images/ic_search.xml rename to 12-networking/projects/starter/desktopApp/src/commonMain/composeResources/drawable/ic_search.xml diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/resources/font/opensans_bold.ttf b/12-networking/projects/starter/desktopApp/src/commonMain/composeResources/font/opensans_bold.ttf similarity index 100% rename from 12-networking/projects/starter/desktopApp/src/jvmMain/resources/font/opensans_bold.ttf rename to 12-networking/projects/starter/desktopApp/src/commonMain/composeResources/font/opensans_bold.ttf diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/resources/font/opensans_extrabold.ttf b/12-networking/projects/starter/desktopApp/src/commonMain/composeResources/font/opensans_extrabold.ttf similarity index 100% rename from 12-networking/projects/starter/desktopApp/src/jvmMain/resources/font/opensans_extrabold.ttf rename to 12-networking/projects/starter/desktopApp/src/commonMain/composeResources/font/opensans_extrabold.ttf diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/resources/font/opensans_light.ttf b/12-networking/projects/starter/desktopApp/src/commonMain/composeResources/font/opensans_light.ttf similarity index 100% rename from 12-networking/projects/starter/desktopApp/src/jvmMain/resources/font/opensans_light.ttf rename to 12-networking/projects/starter/desktopApp/src/commonMain/composeResources/font/opensans_light.ttf diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/resources/font/opensans_regular.ttf b/12-networking/projects/starter/desktopApp/src/commonMain/composeResources/font/opensans_regular.ttf similarity index 100% rename from 12-networking/projects/starter/desktopApp/src/jvmMain/resources/font/opensans_regular.ttf rename to 12-networking/projects/starter/desktopApp/src/commonMain/composeResources/font/opensans_regular.ttf diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/resources/font/opensans_semibold.ttf b/12-networking/projects/starter/desktopApp/src/commonMain/composeResources/font/opensans_semibold.ttf similarity index 100% rename from 12-networking/projects/starter/desktopApp/src/jvmMain/resources/font/opensans_semibold.ttf rename to 12-networking/projects/starter/desktopApp/src/commonMain/composeResources/font/opensans_semibold.ttf diff --git a/12-networking/projects/starter/desktopApp/src/commonMain/composeResources/values/strings.xml b/12-networking/projects/starter/desktopApp/src/commonMain/composeResources/values/strings.xml new file mode 100644 index 00000000..c9820921 --- /dev/null +++ b/12-networking/projects/starter/desktopApp/src/commonMain/composeResources/values/strings.xml @@ -0,0 +1,36 @@ + + learn + Kodeco + + + Home + Bookmark + Latest + Search + + + You currently don\'t have any bookmark. + Loading… + + + Search + + + Hello %s! + + Add to bookmarks + Remove from bookmarks + Share as link + Hey! Check out this article that I\'ve just found: %s. + + Added to bookmarks! + Removed from bookmarks + + + Search for a specific article + Feed icon + More actions + Image preview + Unable to load image preview + User profile + \ No newline at end of file diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/Main.kt b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/Main.kt index 7b46d332..8bf0bd83 100644 --- a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/Main.kt +++ b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/Main.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,16 +38,19 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material.Surface import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Window import androidx.compose.ui.window.application import androidx.compose.ui.window.rememberWindowState +import androidx.lifecycle.viewmodel.compose.viewModel import com.kodeco.learn.data.model.KodecoEntry import com.kodeco.learn.platform.Logger +import com.kodeco.learn.resources.Res +import com.kodeco.learn.resources.app_name import com.kodeco.learn.ui.bookmark.BookmarkViewModel import com.kodeco.learn.ui.home.FeedViewModel import com.kodeco.learn.ui.main.MainScreen import com.kodeco.learn.ui.theme.KodecoTheme -import moe.tlaster.precompose.PreComposeWindow -import moe.tlaster.precompose.viewmodel.viewModel +import org.jetbrains.compose.resources.stringResource import java.awt.Desktop import java.net.URI @@ -61,10 +64,10 @@ fun main() { application { val windowState = rememberWindowState(width = 460.dp, height = 900.dp) - PreComposeWindow( + Window( onCloseRequest = ::exitApplication, state = windowState, - title = "learn" + title = stringResource(Res.string.app_name) ) { bookmarkViewModel = viewModel { BookmarkViewModel() diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/components/ImagePreview.kt b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/components/ImagePreview.kt index 5aa04a0a..21065c38 100644 --- a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/components/ImagePreview.kt +++ b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/components/ImagePreview.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -45,9 +45,14 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.res.painterResource import com.kodeco.learn.platform.Logger +import com.kodeco.learn.resources.Res +import com.kodeco.learn.resources.description_preview +import com.kodeco.learn.resources.description_preview_error +import com.kodeco.learn.resources.ic_brand import com.seiko.imageloader.rememberImagePainter +import org.jetbrains.compose.resources.painterResource +import org.jetbrains.compose.resources.stringResource private const val TAG = "ImagePreview" @@ -65,8 +70,7 @@ fun AddImagePreview( } else { Box { - - val resource = painterResource("images/ic_brand.xml") + val resource = painterResource(Res.drawable.ic_brand) val painter = rememberImagePainter( url = url, @@ -77,7 +81,7 @@ fun AddImagePreview( Image( painter = painter, contentScale = ContentScale.Crop, - contentDescription = "Image preview", + contentDescription = stringResource(Res.string.description_preview), modifier = modifier ) } @@ -100,8 +104,8 @@ fun AddImagePreviewEmpty( color = Color.Transparent ) { - val resource = painterResource("images/ic_brand.xml") - val description = "Unable to load image preview" + val resource = painterResource(Res.drawable.ic_brand) + val description = stringResource(Res.string.description_preview_error) Column( horizontalAlignment = Alignment.CenterHorizontally, diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/bookmark/BookmarkContent.kt b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/bookmark/BookmarkContent.kt index b4812196..1c4f50c9 100644 --- a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/bookmark/BookmarkContent.kt +++ b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/bookmark/BookmarkContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/bookmark/BookmarkViewModel.kt b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/bookmark/BookmarkViewModel.kt index 28b42d5b..4a9a10b6 100644 --- a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/bookmark/BookmarkViewModel.kt +++ b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/bookmark/BookmarkViewModel.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -36,6 +36,8 @@ package com.kodeco.learn.ui.bookmark import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope import com.kodeco.learn.ServiceLocator import com.kodeco.learn.data.model.KodecoEntry import com.kodeco.learn.domain.cb.BookmarkData @@ -43,8 +45,6 @@ import com.kodeco.learn.platform.Logger import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import moe.tlaster.precompose.viewmodel.ViewModel -import moe.tlaster.precompose.viewmodel.viewModelScope private const val TAG = "BookmarkViewModel" diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/common/EmptyContent.kt b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/common/EmptyContent.kt index bd221c2d..ba7b331f 100644 --- a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/common/EmptyContent.kt +++ b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/common/EmptyContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/common/EntryContent.kt b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/common/EntryContent.kt index 8258206a..f00ea9a8 100644 --- a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/common/EntryContent.kt +++ b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/common/EntryContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -47,7 +47,7 @@ import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.BottomSheetScaffoldState import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material3.Divider +import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -55,15 +55,20 @@ import androidx.compose.runtime.MutableState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip -import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.kodeco.learn.components.AddImagePreview import com.kodeco.learn.data.model.KodecoEntry import com.kodeco.learn.platform.Logger +import com.kodeco.learn.resources.Res +import com.kodeco.learn.resources.app_kodeco +import com.kodeco.learn.resources.description_more +import com.kodeco.learn.resources.ic_more import com.kodeco.learn.utils.converterIso8601ToReadableDate import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch +import org.jetbrains.compose.resources.painterResource +import org.jetbrains.compose.resources.stringResource private const val TAG = "EntryContent" @@ -118,7 +123,7 @@ fun AddEntryContent( ) { Text( - text = "Kodeco" + text = stringResource(Res.string.app_kodeco) ) Text( @@ -132,8 +137,8 @@ fun AddEntryContent( horizontalArrangement = Arrangement.End ) { - val resource = painterResource("images/ic_more.xml") - val description = "More actions" + val resource = painterResource(Res.drawable.ic_more) + val description = stringResource(Res.string.description_more) Icon( painter = resource, @@ -167,7 +172,7 @@ fun AddEntryContent( Spacer(modifier = Modifier.height(16.dp)) if (divider) { - Divider( + HorizontalDivider( modifier = Modifier.fillMaxWidth(), thickness = 1.dp ) diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/FeedViewModel.kt b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/FeedViewModel.kt index 451c89ce..08e2d6b6 100644 --- a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/FeedViewModel.kt +++ b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/FeedViewModel.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,13 +38,13 @@ import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateMapOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.snapshots.SnapshotStateMap +import androidx.lifecycle.ViewModel import com.kodeco.learn.ServiceLocator import com.kodeco.learn.data.model.GravatarEntry import com.kodeco.learn.data.model.KodecoEntry import com.kodeco.learn.data.model.PLATFORM import com.kodeco.learn.domain.cb.FeedData import com.kodeco.learn.platform.Logger -import moe.tlaster.precompose.viewmodel.ViewModel private const val TAG = "FeedViewModel" @@ -63,6 +63,7 @@ class FeedViewModel : ViewModel(), FeedData { fun fetchAllFeeds() { Logger.d(TAG, "fetchAllFeeds") + _items[PLATFORM.ALL] = presenter.allFeeds } fun fetchMyGravatar() { diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/HomeContent.kt b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/HomeContent.kt index 99dd0f0d..30a13cbc 100644 --- a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/HomeContent.kt +++ b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/HomeContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/HomeSheetContent.kt b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/HomeSheetContent.kt index 3dcc478c..454cc983 100644 --- a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/HomeSheetContent.kt +++ b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/HomeSheetContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -48,8 +48,13 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.kodeco.learn.data.model.KodecoEntry import com.kodeco.learn.platform.Logger +import com.kodeco.learn.resources.Res +import com.kodeco.learn.resources.action_add_bookmarks +import com.kodeco.learn.resources.action_remove_bookmarks +import com.kodeco.learn.resources.action_share_link import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch +import org.jetbrains.compose.resources.stringResource private const val TAG = "HomeSheetContent" @@ -82,9 +87,9 @@ fun HomeSheetContent( ) { val text = if (item.value.bookmarked) { - "Remove from bookmarks" + stringResource(Res.string.action_remove_bookmarks) } else { - "Add to bookmarks" + stringResource(Res.string.action_add_bookmarks) } Text( @@ -107,7 +112,7 @@ fun HomeSheetContent( } ) { Text( - text = "Share as link", + text = stringResource(Res.string.action_share_link), modifier = Modifier .fillMaxWidth() .padding(start = 16.dp, top = 12.dp, end = 16.dp, bottom = 24.dp) diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/latest/LatestContent.kt b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/latest/LatestContent.kt index fa2e9f5f..f88cd468 100644 --- a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/latest/LatestContent.kt +++ b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/latest/LatestContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/BottomNavigationScreens.kt b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/BottomNavigationScreens.kt index 14220282..83b09871 100644 --- a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/BottomNavigationScreens.kt +++ b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/BottomNavigationScreens.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -36,54 +36,65 @@ package com.kodeco.learn.ui.main import androidx.compose.material3.Icon import androidx.compose.runtime.Composable -import androidx.compose.ui.res.painterResource +import com.kodeco.learn.resources.Res +import com.kodeco.learn.resources.ic_bookmarks +import com.kodeco.learn.resources.ic_home +import com.kodeco.learn.resources.ic_latest +import com.kodeco.learn.resources.ic_search +import com.kodeco.learn.resources.navigation_bookmark +import com.kodeco.learn.resources.navigation_home +import com.kodeco.learn.resources.navigation_latest +import com.kodeco.learn.resources.navigation_search +import org.jetbrains.compose.resources.StringResource +import org.jetbrains.compose.resources.painterResource +import org.jetbrains.compose.resources.stringResource sealed class BottomNavigationScreens( val route: String, - val title: String, + val title: StringResource, val icon: @Composable () -> Unit ) { data object Home : BottomNavigationScreens( route = "Home", - title = "Home", + title = Res.string.navigation_home, icon = { Icon( - painter = painterResource("images/ic_home.xml"), - contentDescription = "Home" + painter = painterResource(Res.drawable.ic_home), + contentDescription = stringResource(Res.string.navigation_home) ) } ) data object Bookmark : BottomNavigationScreens( route = "Bookmark", - title = "Bookmark", + title = Res.string.navigation_bookmark, icon = { Icon( - painter = painterResource("images/ic_bookmarks.xml"), - contentDescription = "Bookmark" + painter = painterResource(Res.drawable.ic_bookmarks), + contentDescription = stringResource(Res.string.navigation_bookmark) ) } ) data object Latest : BottomNavigationScreens( route = "Latest", - title = "Latest", + title = Res.string.navigation_latest, icon = { Icon( - painter = painterResource("images/ic_latest.xml"), - contentDescription = "Latest" + painter = painterResource(Res.drawable.ic_latest), + contentDescription = stringResource(Res.string.navigation_latest) ) } ) data object Search : BottomNavigationScreens( route = "Search", - title = "Search", + title = Res.string.navigation_search, icon = { Icon( - painter = painterResource("images/ic_search.xml"), - contentDescription = "Search" + painter = painterResource(Res.drawable.ic_search), + contentDescription = stringResource(Res.string.navigation_search) ) } ) diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainBottomBar.kt b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainBottomBar.kt deleted file mode 100644 index 9a0aa349..00000000 --- a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainBottomBar.kt +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2023 Kodeco Inc - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, - * distribute, sublicense, create a derivative work, and/or sell copies of the - * Software in any work that is designed, intended, or marketed for pedagogical or - * instructional purposes related to programming, coding, application development, - * or information technology. Permission for such use, copying, modification, - * merger, publication, distribution, sublicensing, creation of derivative works, - * or sale is expressly withheld. - * - * This project and source code may use libraries or frameworks that are - * released under various Open-Source licenses. Use of those libraries and - * frameworks are governed by their own individual licenses. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.kodeco.learn.ui.main - -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.material3.BottomAppBar -import androidx.compose.material3.NavigationBarItem -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState -import androidx.compose.runtime.mutableIntStateOf -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import moe.tlaster.precompose.navigation.Navigator - -private lateinit var selectedIndex: MutableState - -@Composable -fun MainBottomBar( - navController: Navigator, - items: List -) { - - Column { - Row( - modifier = Modifier - .fillMaxWidth() - .height(1.dp) - ) {} - - AppBottomNavigation( - navController = navController, - items = items - ) - } -} - -@Composable -private fun AppBottomNavigation( - navController: Navigator, - items: List -) { - BottomAppBar { - - selectedIndex = remember { mutableIntStateOf(0) } - - items.forEachIndexed { index, screen -> - - val isSelected = selectedIndex.value == index - - NavigationBarItem( - icon = { - screen.icon() - }, - label = { - Text( - text = screen.title - ) - }, - selected = isSelected, - alwaysShowLabel = true, - onClick = { - if (!isSelected) { - selectedIndex.value = index - navController.navigate(screen.route) - } - } - ) - } - } -} \ No newline at end of file diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainContent.kt b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainContent.kt index fd19e217..14f2a144 100644 --- a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainContent.kt +++ b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -48,15 +48,11 @@ import com.kodeco.learn.ui.home.HomeContent import com.kodeco.learn.ui.latest.LatestContent import com.kodeco.learn.ui.search.SearchContent import kotlinx.coroutines.CoroutineScope -import moe.tlaster.precompose.navigation.NavHost -import moe.tlaster.precompose.navigation.Navigator - -private val DEFAULT_SCREEN = BottomNavigationScreens.Home @OptIn(ExperimentalMaterialApi::class) @Composable fun MainContent( - navController: Navigator, + destination: BottomNavigationScreens, coroutineScope: CoroutineScope, bottomSheetScaffoldState: BottomSheetScaffoldState, selected: MutableState, @@ -67,7 +63,7 @@ fun MainContent( Column { MainScreenNavigationConfigurations( - navController = navController, + destination = destination, coroutineScope = coroutineScope, bottomSheetScaffoldState = bottomSheetScaffoldState, selected = selected, @@ -81,7 +77,7 @@ fun MainContent( @OptIn(ExperimentalMaterialApi::class) @Composable private fun MainScreenNavigationConfigurations( - navController: Navigator, + destination: BottomNavigationScreens, coroutineScope: CoroutineScope, bottomSheetScaffoldState: BottomSheetScaffoldState, selected: MutableState, @@ -90,41 +86,38 @@ private fun MainScreenNavigationConfigurations( onOpenEntry: (String) -> Unit ) { - NavHost( - navigator = navController, - initialRoute = DEFAULT_SCREEN.route - ) { - scene(BottomNavigationScreens.Home.route) { + when(destination) { + BottomNavigationScreens.Home -> { HomeContent( - selected = selected, - items = feeds, - coroutineScope = coroutineScope, - bottomSheetScaffoldState = bottomSheetScaffoldState, - onOpenEntry = onOpenEntry + selected = selected, + items = feeds, + coroutineScope = coroutineScope, + bottomSheetScaffoldState = bottomSheetScaffoldState, + onOpenEntry = onOpenEntry ) } - scene(BottomNavigationScreens.Bookmark.route) { + BottomNavigationScreens.Bookmark -> { BookmarkContent( - selected = selected, - items = bookmarks, - coroutineScope = coroutineScope, - bottomSheetScaffoldState = bottomSheetScaffoldState, - onOpenEntry = onOpenEntry + selected = selected, + items = bookmarks, + coroutineScope = coroutineScope, + bottomSheetScaffoldState = bottomSheetScaffoldState, + onOpenEntry = onOpenEntry ) } - scene(BottomNavigationScreens.Latest.route) { + BottomNavigationScreens.Latest -> { LatestContent( - items = feeds, - onOpenEntry = onOpenEntry + items = feeds, + onOpenEntry = onOpenEntry ) } - scene(BottomNavigationScreens.Search.route) { + BottomNavigationScreens.Search -> { SearchContent( - selected = selected, - items = feeds, - coroutineScope = coroutineScope, - bottomSheetScaffoldState = bottomSheetScaffoldState, - onOpenEntry = onOpenEntry + selected = selected, + items = feeds, + coroutineScope = coroutineScope, + bottomSheetScaffoldState = bottomSheetScaffoldState, + onOpenEntry = onOpenEntry ) } } diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainScreen.kt b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainScreen.kt index 1fc49b25..7051161d 100644 --- a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainScreen.kt +++ b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainScreen.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -40,7 +40,8 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.BottomSheetScaffold import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.rememberBottomSheetScaffoldState -import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteScaffold import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.State @@ -54,8 +55,9 @@ import com.kodeco.learn.data.model.GravatarEntry import com.kodeco.learn.data.model.KodecoEntry import com.kodeco.learn.data.model.PLATFORM import com.kodeco.learn.ui.home.HomeSheetContent -import moe.tlaster.precompose.navigation.rememberNavigator +import org.jetbrains.compose.resources.stringResource +private val DEFAULT_SCREEN = BottomNavigationScreens.Home private lateinit var selected: MutableState @OptIn(ExperimentalMaterialApi::class) @@ -76,7 +78,9 @@ fun MainScreen( BottomNavigationScreens.Search ) - val navController = rememberNavigator() + val currentDestination = remember { + mutableStateOf(DEFAULT_SCREEN) + } val coroutineScope = rememberCoroutineScope() val bottomSheetScaffoldState = rememberBottomSheetScaffoldState() @@ -100,33 +104,42 @@ fun MainScreen( scaffoldState = bottomSheetScaffoldState, sheetPeekHeight = 0.dp ) { - Scaffold( - topBar = { + NavigationSuiteScaffold( + navigationSuiteItems = { + bottomNavigationItems.forEach { screen -> + item( + icon = { + screen.icon() + }, + label = { + Text( + text = stringResource(screen.title) + ) + }, + selected = screen == currentDestination.value, + onClick = { currentDestination.value = screen } + ) + } + }, + content = { + Column( + modifier = Modifier.padding(it) + ) { MainTopAppBar( - profile = profile + profile = profile ) - }, - bottomBar = { - MainBottomBar( - navController = navController, - items = bottomNavigationItems + + MainContent( + destination = currentDestination.value, + coroutineScope = coroutineScope, + bottomSheetScaffoldState = bottomSheetScaffoldState, + selected = selected, + feeds = feeds, + bookmarks = bookmarks, + onOpenEntry = onOpenEntry ) - }, - content = { - Column( - modifier = Modifier.padding(it) - ) { - MainContent( - navController = navController, - coroutineScope = coroutineScope, - bottomSheetScaffoldState = bottomSheetScaffoldState, - selected = selected, - feeds = feeds, - bookmarks = bookmarks, - onOpenEntry = onOpenEntry - ) - } } + } ) } } \ No newline at end of file diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainTopAppBar.kt b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainTopAppBar.kt index 892fd674..97a009cd 100644 --- a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainTopAppBar.kt +++ b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainTopAppBar.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -49,6 +49,10 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.dp import com.kodeco.learn.components.AddImagePreview import com.kodeco.learn.data.model.GravatarEntry +import com.kodeco.learn.resources.Res +import com.kodeco.learn.resources.app_name +import com.kodeco.learn.resources.description_profile +import org.jetbrains.compose.resources.stringResource @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -59,7 +63,7 @@ fun MainTopAppBar( CenterAlignedTopAppBar( title = { Text( - text = "learn" + text = stringResource(Res.string.app_name), ) }, actions = { @@ -70,7 +74,7 @@ fun MainTopAppBar( if (avatarUrl == null) { Icon( imageVector = Icons.Filled.Person, - contentDescription = "User profile" + contentDescription = stringResource(Res.string.description_profile) ) } else { AddImagePreview( diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/search/SearchContent.kt b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/search/SearchContent.kt index 4e2a4d00..b816f6b3 100644 --- a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/search/SearchContent.kt +++ b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/search/SearchContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -51,13 +51,15 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.snapshots.SnapshotStateMap import androidx.compose.ui.Modifier import androidx.compose.ui.focus.onFocusChanged -import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import com.kodeco.learn.data.model.KodecoEntry import com.kodeco.learn.data.model.PLATFORM import com.kodeco.learn.platform.Logger +import com.kodeco.learn.resources.Res +import com.kodeco.learn.resources.ic_search import com.kodeco.learn.ui.common.AddEntryContent import kotlinx.coroutines.CoroutineScope +import org.jetbrains.compose.resources.painterResource private const val TAG = "SearchContent" @@ -140,7 +142,7 @@ fun AddSearchField(search: MutableState) { ) }, leadingIcon = { - val resource = painterResource("images/ic_search.xml") + val resource = painterResource(Res.drawable.ic_search) val description = "Search for a specific article" Icon( diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Color.kt b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Color.kt index a594ad49..2e781c25 100644 --- a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Color.kt +++ b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Color.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Shape.kt b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Shape.kt index 8964a873..329ab7f5 100644 --- a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Shape.kt +++ b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Shape.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Theme.kt b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Theme.kt index 49e5b7eb..50c564f8 100644 --- a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Theme.kt +++ b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Theme.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -70,7 +70,7 @@ fun KodecoTheme( MaterialTheme( colorScheme = colorScheme, - typography = Typography, + typography = Typography(OpenSansFontFamily()), content = content ) } \ No newline at end of file diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Type.kt b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Type.kt index cd4e4933..48aa65b3 100644 --- a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Type.kt +++ b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Type.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -35,59 +35,102 @@ package com.kodeco.learn.ui.theme import androidx.compose.material3.Typography +import androidx.compose.runtime.Composable import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.platform.Font import androidx.compose.ui.unit.sp +import com.kodeco.learn.resources.Res +import com.kodeco.learn.resources.opensans_bold +import com.kodeco.learn.resources.opensans_extrabold +import com.kodeco.learn.resources.opensans_light +import com.kodeco.learn.resources.opensans_regular +import com.kodeco.learn.resources.opensans_semibold +import org.jetbrains.compose.resources.Font private val fontSizeBig = 16.sp private val fontSizeMedium = 15.sp private val fontSizeSmall = 14.sp private val fontSizeTiny = 12.sp -private val OpenSansFontFamily = FontFamily( - Font("font/opensans_bold.ttf", FontWeight.Bold), - Font("font/opensans_extrabold.ttf", FontWeight.ExtraBold), - Font("font/opensans_light.ttf", FontWeight.Light), - Font("font/opensans_regular.ttf", FontWeight.Normal), - Font("font/opensans_semibold.ttf", FontWeight.SemiBold), +@Composable +fun OpenSansFontFamily() = FontFamily( + Font(Res.font.opensans_bold, FontWeight.Bold, FontStyle.Normal), + Font(Res.font.opensans_extrabold, FontWeight.ExtraBold, FontStyle.Normal), + Font(Res.font.opensans_light, FontWeight.Light, FontStyle.Normal), + Font(Res.font.opensans_regular, FontWeight.Normal, FontStyle.Normal), + Font(Res.font.opensans_semibold, FontWeight.SemiBold, FontStyle.Normal) ) // Set of Material typography styles to start with -val Typography = Typography( +fun Typography(family: FontFamily) = Typography( headlineLarge = TextStyle( - fontFamily = OpenSansFontFamily, + fontFamily = family, fontWeight = FontWeight.Bold, fontSize = fontSizeMedium ), headlineMedium = TextStyle( - fontFamily = OpenSansFontFamily, + fontFamily = family, fontWeight = FontWeight.Normal, fontSize = fontSizeSmall ), headlineSmall = TextStyle( - fontFamily = OpenSansFontFamily, + fontFamily = family, fontWeight = FontWeight.Bold, fontSize = fontSizeTiny ), bodyLarge = TextStyle( - fontFamily = OpenSansFontFamily, + fontFamily = family, fontWeight = FontWeight.Normal, fontSize = fontSizeBig ), bodyMedium = TextStyle( - fontFamily = OpenSansFontFamily, + fontFamily = family, fontWeight = FontWeight.Bold, fontSize = fontSizeSmall ), bodySmall = TextStyle( - fontFamily = OpenSansFontFamily, + fontFamily = family, + fontSize = fontSizeSmall + ), + + titleLarge = TextStyle( + fontFamily = family, + fontWeight = FontWeight.Normal, + fontSize = fontSizeBig + ), + + titleMedium = TextStyle( + fontFamily = family, + fontWeight = FontWeight.Bold, + fontSize = fontSizeSmall + ), + + titleSmall = TextStyle( + fontFamily = family, + fontSize = fontSizeSmall + ), + + labelLarge = TextStyle( + fontFamily = family, + fontWeight = FontWeight.Normal, + fontSize = fontSizeBig + ), + + labelMedium = TextStyle( + fontFamily = family, + fontWeight = FontWeight.Bold, + fontSize = fontSizeSmall + ), + + labelSmall = TextStyle( + fontFamily = family, fontSize = fontSizeSmall ) ) \ No newline at end of file diff --git a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/utils/Utils.kt b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/utils/Utils.kt index a92d0ad1..6e58ae85 100644 --- a/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/utils/Utils.kt +++ b/12-networking/projects/starter/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/utils/Utils.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -35,7 +35,7 @@ package com.kodeco.learn.utils import com.kodeco.learn.platform.Logger -import kotlinx.datetime.toInstant +import kotlinx.datetime.Instant import java.text.SimpleDateFormat import java.util.Date import java.util.Locale @@ -47,7 +47,7 @@ private val simpleDateFormat = SimpleDateFormat("yyyy/MM/dd", Locale.getDefault( fun converterIso8601ToReadableDate(date: String): String { return try { - val instant = date.toInstant() + val instant = Instant.parse(date) val millis = Date(instant.toEpochMilliseconds()) return simpleDateFormat.format(millis) } catch (e: Exception) { diff --git a/12-networking/projects/starter/gradle.properties b/12-networking/projects/starter/gradle.properties index 1677b55e..27359d2f 100644 --- a/12-networking/projects/starter/gradle.properties +++ b/12-networking/projects/starter/gradle.properties @@ -9,7 +9,6 @@ org.gradle.jvmargs=-Xmx6g -XX:+UseParallelGC # MPP kotlin.mpp.enableCInteropCommonization=true kotlin.mpp.stability.nowarn=true -kotlin.mpp.androidSourceSetLayoutVersion=2 # https://blog.jetbrains.com/kotlin/2022/07/a-new-approach-to-incremental-compilation-in-kotlin/ kotlin.incremental.useClasspathSnapshot=true diff --git a/12-networking/projects/starter/gradle/libs.versions.toml b/12-networking/projects/starter/gradle/libs.versions.toml index 8a1edb93..719c7269 100644 --- a/12-networking/projects/starter/gradle/libs.versions.toml +++ b/12-networking/projects/starter/gradle/libs.versions.toml @@ -1,23 +1,22 @@ [versions] -gradle = "8.1.2" -android-sdk-compile = "34" +gradle = "8.8.0" +android-sdk-compile = "35" android-sdk-min = "24" -android-sdk-target = "34" -android-compose-compiler = "1.5.3" -android-material = "1.10.0" -androidx-compose-bom = "2023.10.00" -androidx-lifecycle-runtime-ktx = "2.6.2" -androidx-navigation-compose = "2.7.4" -coil = "2.4.0" -image-loader = "1.6.7" +android-sdk-target = "35" +android-material = "1.12.0" +androidx-compose-bom = "2025.01.01" +androidx-lifecycle-runtime-ktx = "2.8.7" +androidx-navigation-compose = "2.8.6" +coil = "2.7.0" +image-loader = "1.10.0" korio = "4.0.10" -kotlin = "1.9.10" -kotlinx-datetime = "0.4.1" -kotlinx-serialization-json = "1.6.0" -jetbrains-compose = "1.5.3" -okio = "3.5.0" -precompose = "1.5.3" -sqldelight = "2.0.0" +kotlin = "2.1.0" +kotlinx-datetime = "0.6.1" +kotlinx-serialization-json = "1.7.3" +jetbrains-compose = "1.7.3" +jetbrains-compose-lifecycle = "2.8.0" +okio = "3.10.2" +sqldelight = "2.0.2" [libraries] android-material = { module = "com.google.android.material:material", version.ref = "android-material" } @@ -32,6 +31,8 @@ androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" } androidx-lifecycle-runtime-ktx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "androidx-lifecycle-runtime-ktx" } androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "androidx-navigation-compose" } +jetbrains-compose-lifecycle = { module = "org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "jetbrains-compose-lifecycle" } + cash-sqldelight-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" } cash-sqldelight-jvm = { module = "app.cash.sqldelight:sqlite-driver", version.ref = "sqldelight" } cash-sqldelight-native = { module = "app.cash.sqldelight:native-driver", version.ref = "sqldelight" } @@ -41,15 +42,14 @@ korio = { module = "com.soywiz.korlibs.korio:korio", version.ref = "korio" } kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinx-datetime" } kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization-json" } okio = { module = "com.squareup.okio:okio", version.ref = "okio" } -precompose-viewmodel = { module = "moe.tlaster:precompose-viewmodel", version.ref = "precompose" } -precompose = { module = "moe.tlaster:precompose", version.ref = "precompose" } [plugins] android-application = { id = "com.android.application", version.ref = "gradle" } android-library = { id = "com.android.library", version.ref = "gradle" } cash-sqldelight = { id = "app.cash.sqldelight", version.ref = "sqldelight" } jetbrains-compose = { id = "org.jetbrains.compose", version.ref = "jetbrains-compose" } +jetbrains-compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } jetbrains-kotlin = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } jetbrains-kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } -jetbrains-kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" } jetbrains-kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } +jetbrains-kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" } \ No newline at end of file diff --git a/12-networking/projects/starter/gradle/wrapper/gradle-wrapper.properties b/12-networking/projects/starter/gradle/wrapper/gradle-wrapper.properties index 4b932409..5a450493 100644 --- a/12-networking/projects/starter/gradle/wrapper/gradle-wrapper.properties +++ b/12-networking/projects/starter/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Wed Jul 21 00:48:56 WEST 2021 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME diff --git a/12-networking/projects/starter/iosApp/iosApp/BookmarkView.swift b/12-networking/projects/starter/iosApp/iosApp/BookmarkView.swift index 103f3a54..2760077d 100644 --- a/12-networking/projects/starter/iosApp/iosApp/BookmarkView.swift +++ b/12-networking/projects/starter/iosApp/iosApp/BookmarkView.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/iosApp/iosApp/ContentView.swift b/12-networking/projects/starter/iosApp/iosApp/ContentView.swift index a067502c..233c88f6 100644 --- a/12-networking/projects/starter/iosApp/iosApp/ContentView.swift +++ b/12-networking/projects/starter/iosApp/iosApp/ContentView.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/iosApp/iosApp/HomeView.swift b/12-networking/projects/starter/iosApp/iosApp/HomeView.swift index 43052702..4cb0245f 100644 --- a/12-networking/projects/starter/iosApp/iosApp/HomeView.swift +++ b/12-networking/projects/starter/iosApp/iosApp/HomeView.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/iosApp/iosApp/KodecoEntryViewModel.swift b/12-networking/projects/starter/iosApp/iosApp/KodecoEntryViewModel.swift index 5239b41d..531e26e0 100644 --- a/12-networking/projects/starter/iosApp/iosApp/KodecoEntryViewModel.swift +++ b/12-networking/projects/starter/iosApp/iosApp/KodecoEntryViewModel.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/iosApp/iosApp/LatestView.swift b/12-networking/projects/starter/iosApp/iosApp/LatestView.swift index 3b004330..e87ff438 100644 --- a/12-networking/projects/starter/iosApp/iosApp/LatestView.swift +++ b/12-networking/projects/starter/iosApp/iosApp/LatestView.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/iosApp/iosApp/MainToolbarContent.swift b/12-networking/projects/starter/iosApp/iosApp/MainToolbarContent.swift index 51c10955..8fb616f5 100644 --- a/12-networking/projects/starter/iosApp/iosApp/MainToolbarContent.swift +++ b/12-networking/projects/starter/iosApp/iosApp/MainToolbarContent.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/iosApp/iosApp/SearchView.swift b/12-networking/projects/starter/iosApp/iosApp/SearchView.swift index 2c4b4089..91be014e 100644 --- a/12-networking/projects/starter/iosApp/iosApp/SearchView.swift +++ b/12-networking/projects/starter/iosApp/iosApp/SearchView.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/iosApp/iosApp/common/KodecoEntryRow.swift b/12-networking/projects/starter/iosApp/iosApp/common/KodecoEntryRow.swift index 600de5ba..087a489d 100644 --- a/12-networking/projects/starter/iosApp/iosApp/common/KodecoEntryRow.swift +++ b/12-networking/projects/starter/iosApp/iosApp/common/KodecoEntryRow.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal @@ -58,7 +58,6 @@ struct KodecoEntryRow: View { VStack(alignment: .leading) { HStack { if item.imageUrl.isEmpty { - Rectangle().foregroundColor(.gray) Image("kodeco") .resizable() .frame(width: 50, height: 50) diff --git a/12-networking/projects/starter/iosApp/iosApp/extensions/BookmarkClient.swift b/12-networking/projects/starter/iosApp/iosApp/extensions/BookmarkClient.swift index a962b101..6f2435ec 100644 --- a/12-networking/projects/starter/iosApp/iosApp/extensions/BookmarkClient.swift +++ b/12-networking/projects/starter/iosApp/iosApp/extensions/BookmarkClient.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/iosApp/iosApp/extensions/FeedClient.swift b/12-networking/projects/starter/iosApp/iosApp/extensions/FeedClient.swift index 9f76194d..f6bf44a2 100644 --- a/12-networking/projects/starter/iosApp/iosApp/extensions/FeedClient.swift +++ b/12-networking/projects/starter/iosApp/iosApp/extensions/FeedClient.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal @@ -58,6 +58,7 @@ public class FeedClient { public func fetchFeeds(completion: @escaping FeedHandler) { handler = completion + handler?(PLATFORM.all.description(), feedPresenter.allFeeds) } public func fetchLinkImage(_ platform: PLATFORM, _ id: String, _ link: String, completion: @escaping FeedHandlerImage) { diff --git a/12-networking/projects/starter/iosApp/iosApp/iOSApp.swift b/12-networking/projects/starter/iosApp/iosApp/iOSApp.swift index ace71a32..868ad2fe 100644 --- a/12-networking/projects/starter/iosApp/iosApp/iOSApp.swift +++ b/12-networking/projects/starter/iosApp/iosApp/iOSApp.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/iosApp/iosApp/utils/Actions.swift b/12-networking/projects/starter/iosApp/iosApp/utils/Actions.swift index 35253b96..1337bb35 100644 --- a/12-networking/projects/starter/iosApp/iosApp/utils/Actions.swift +++ b/12-networking/projects/starter/iosApp/iosApp/utils/Actions.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/iosApp/iosApp/utils/Utils.swift b/12-networking/projects/starter/iosApp/iosApp/utils/Utils.swift index 4463f1f3..621ebcf4 100644 --- a/12-networking/projects/starter/iosApp/iosApp/utils/Utils.swift +++ b/12-networking/projects/starter/iosApp/iosApp/utils/Utils.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/settings.gradle.kts b/12-networking/projects/starter/settings.gradle.kts index 56713c61..97b54fa6 100644 --- a/12-networking/projects/starter/settings.gradle.kts +++ b/12-networking/projects/starter/settings.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/shared-dto/build.gradle.kts b/12-networking/projects/starter/shared-dto/build.gradle.kts index 3deed4a4..23ab3b4d 100644 --- a/12-networking/projects/starter/shared-dto/build.gradle.kts +++ b/12-networking/projects/starter/shared-dto/build.gradle.kts @@ -1,53 +1,69 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + plugins { - kotlin("multiplatform") - id("com.android.library") - alias(libs.plugins.jetbrains.kotlin.parcelize) - alias(libs.plugins.jetbrains.kotlin.serialization) + kotlin("multiplatform") + id("com.android.library") + + alias(libs.plugins.jetbrains.kotlin.parcelize) + alias(libs.plugins.jetbrains.kotlin.serialization) } -@OptIn(org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi::class) kotlin { - targetHierarchy.default() - androidTarget() + androidTarget { + compilerOptions { + // Issue #KT-58892: https://youtrack.jetbrains.com/issue/KT-58892/K2-Parcelize-doesnt-work-in-common-code-when-expect-annotation-is-actualized-with-typealias-to-Parcelize + freeCompilerArgs.addAll("-P", "plugin:org.jetbrains.kotlin.parcelize:additionalAnnotation=com.kodeco.learn.platform.Parcelize") + } + compilations.all { + compileTaskProvider.configure { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_17) + } + } + } + } - jvm() + jvm() - listOf( - iosX64(), - iosArm64(), - iosSimulatorArm64() - ).forEach { - it.binaries.framework { - baseName = "shared-dto" - } + listOf( + iosX64(), + iosArm64(), + iosSimulatorArm64() + ).forEach { + it.binaries.framework { + baseName = "shared-dto" } + } - sourceSets { - getByName("commonMain") { - dependencies { - implementation(libs.kotlinx.serialization.json) - } - } - getByName("commonTest") { - dependencies { - implementation(kotlin("test")) - } - } + sourceSets { + commonMain { + dependencies { + implementation(libs.kotlinx.serialization.json) + } } + } } android { - namespace = "com.kodeco.shared" + namespace = "com.kodeco.shared" - compileSdk = 33 + compileSdk = libs.versions.android.sdk.compile.get().toInt() - defaultConfig { - minSdk = 24 - } + defaultConfig { + minSdk = libs.versions.android.sdk.min.get().toInt() + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } +} - compileOptions { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 +kotlin.targets.configureEach { + compilations.configureEach { + compileTaskProvider.get().compilerOptions { + freeCompilerArgs.add("-Xexpect-actual-classes") } + } } \ No newline at end of file diff --git a/12-networking/projects/starter/shared-dto/src/androidMain/kotlin/com/kodeco/learn/platform/Parcelable.android.kt b/12-networking/projects/starter/shared-dto/src/androidMain/kotlin/com/kodeco/learn/platform/Parcelable.android.kt index 1fc85362..fefdce70 100644 --- a/12-networking/projects/starter/shared-dto/src/androidMain/kotlin/com/kodeco/learn/platform/Parcelable.android.kt +++ b/12-networking/projects/starter/shared-dto/src/androidMain/kotlin/com/kodeco/learn/platform/Parcelable.android.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -35,4 +35,4 @@ package com.kodeco.learn.platform actual typealias Parcelable = android.os.Parcelable -actual typealias Parcelize = kotlinx.android.parcel.Parcelize \ No newline at end of file +actual typealias Parcelize = kotlinx.parcelize.Parcelize \ No newline at end of file diff --git a/12-networking/projects/starter/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/KodecoSerializer.kt b/12-networking/projects/starter/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/KodecoSerializer.kt index e3bc23dd..e6f73d77 100644 --- a/12-networking/projects/starter/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/KodecoSerializer.kt +++ b/12-networking/projects/starter/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/KodecoSerializer.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -62,5 +62,5 @@ object KodecoSerializer : KSerializer { } private fun findByKey(key: String, default: PLATFORM = PLATFORM.ALL): PLATFORM { - return PLATFORM.values().find { it.value.lowercase() == key.lowercase() } ?: default + return PLATFORM.entries.find { it.value == key } ?: default } \ No newline at end of file diff --git a/12-networking/projects/starter/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/GravatarContent.kt b/12-networking/projects/starter/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/GravatarContent.kt index 3f93c73d..09160a3b 100644 --- a/12-networking/projects/starter/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/GravatarContent.kt +++ b/12-networking/projects/starter/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/GravatarContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/KodecoContent.kt b/12-networking/projects/starter/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/KodecoContent.kt index 7f88308d..272cbcc9 100644 --- a/12-networking/projects/starter/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/KodecoContent.kt +++ b/12-networking/projects/starter/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/KodecoContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/KodecoEntry.kt b/12-networking/projects/starter/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/KodecoEntry.kt index bae3fe09..d028d2c8 100644 --- a/12-networking/projects/starter/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/KodecoEntry.kt +++ b/12-networking/projects/starter/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/KodecoEntry.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,8 +38,8 @@ import com.kodeco.learn.platform.Parcelable import com.kodeco.learn.platform.Parcelize import kotlinx.serialization.Serializable -@Serializable @Parcelize +@Serializable data class KodecoEntry( val id: String = "", val link: String = "", diff --git a/12-networking/projects/starter/shared-dto/src/commonMain/kotlin/com/kodeco/learn/platform/Parcelable.common.kt b/12-networking/projects/starter/shared-dto/src/commonMain/kotlin/com/kodeco/learn/platform/Parcelable.common.kt index eff22a1b..b2bc0d45 100644 --- a/12-networking/projects/starter/shared-dto/src/commonMain/kotlin/com/kodeco/learn/platform/Parcelable.common.kt +++ b/12-networking/projects/starter/shared-dto/src/commonMain/kotlin/com/kodeco/learn/platform/Parcelable.common.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/shared-dto/src/iosMain/kotlin/com/kodeco/learn/platform/Parcelable.ios.kt b/12-networking/projects/starter/shared-dto/src/iosMain/kotlin/com/kodeco/learn/platform/Parcelable.ios.kt index 540759c2..86d99b50 100644 --- a/12-networking/projects/starter/shared-dto/src/iosMain/kotlin/com/kodeco/learn/platform/Parcelable.ios.kt +++ b/12-networking/projects/starter/shared-dto/src/iosMain/kotlin/com/kodeco/learn/platform/Parcelable.ios.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/shared-dto/src/jvmMain/kotlin/com/kodeco/learn/platform/Parcelable.desktop.kt b/12-networking/projects/starter/shared-dto/src/jvmMain/kotlin/com/kodeco/learn/platform/Parcelable.jvm.kt similarity index 98% rename from 12-networking/projects/starter/shared-dto/src/jvmMain/kotlin/com/kodeco/learn/platform/Parcelable.desktop.kt rename to 12-networking/projects/starter/shared-dto/src/jvmMain/kotlin/com/kodeco/learn/platform/Parcelable.jvm.kt index 540759c2..86d99b50 100644 --- a/12-networking/projects/starter/shared-dto/src/jvmMain/kotlin/com/kodeco/learn/platform/Parcelable.desktop.kt +++ b/12-networking/projects/starter/shared-dto/src/jvmMain/kotlin/com/kodeco/learn/platform/Parcelable.jvm.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/shared/build.gradle.kts b/12-networking/projects/starter/shared/build.gradle.kts index 90f4cba7..1ed969f6 100644 --- a/12-networking/projects/starter/shared/build.gradle.kts +++ b/12-networking/projects/starter/shared/build.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,19 +32,18 @@ * THE SOFTWARE. */ -@file:Suppress("OPT_IN_USAGE") - +import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework plugins { alias(libs.plugins.android.library) alias(libs.plugins.jetbrains.kotlin.multiplatform) - alias(libs.plugins.jetbrains.kotlin.parcelize) alias(libs.plugins.jetbrains.kotlin.serialization) + alias(libs.plugins.jetbrains.kotlin.parcelize) alias(libs.plugins.cash.sqldelight) } -version = "2.0" +version = "3.0" sqldelight { databases { @@ -72,9 +71,21 @@ android { } kotlin { - androidTarget() + androidTarget { + compilerOptions { + // Issue #KT-58892: https://youtrack.jetbrains.com/issue/KT-58892/K2-Parcelize-doesnt-work-in-common-code-when-expect-annotation-is-actualized-with-typealias-to-Parcelize + freeCompilerArgs.addAll("-P", "plugin:org.jetbrains.kotlin.parcelize:additionalAnnotation=com.kodeco.learn.platform.Parcelize") + } + compilations.all { + compileTaskProvider.configure { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_17) + } + } + } + } - jvm("desktop") + jvm() val xcf = XCFramework("SharedKit") @@ -92,53 +103,45 @@ kotlin { } sourceSets { - targetHierarchy.default() + applyDefaultHierarchyTemplate() - getByName("commonMain") { - dependencies { - api(project(":shared-dto")) + commonMain.dependencies { + api(project(":shared-dto")) - implementation(libs.kotlinx.datetime) - implementation(libs.kotlinx.serialization.json) + implementation(libs.kotlinx.datetime) + implementation(libs.kotlinx.serialization.json) - implementation(libs.okio) - implementation(libs.korio) - } + implementation(libs.okio) + implementation(libs.korio) } - getByName("commonTest") { - dependencies { - implementation(kotlin("test-common")) - implementation(kotlin("test-annotations-common")) - } + commonTest.dependencies { + implementation(kotlin("test-common")) + implementation(kotlin("test-annotations-common")) } - getByName("androidMain") { - dependencies { - implementation(libs.cash.sqldelight.android) - } + androidMain.dependencies { + implementation(libs.cash.sqldelight.android) } - getByName("androidUnitTest") { - dependencies { - implementation(kotlin("test-junit")) - } + androidUnitTest.dependencies { + implementation(kotlin("test-junit")) } - getByName("desktopMain") { - dependencies { - implementation(libs.cash.sqldelight.jvm) - } + jvmMain.dependencies { + implementation(libs.cash.sqldelight.jvm) } - getByName("iosMain") { - dependencies { - implementation(libs.cash.sqldelight.native) - } + iosMain.dependencies { + implementation(libs.cash.sqldelight.native) } } } -kotlin.sourceSets.all { - languageSettings.optIn("kotlin.RequiresOptIn") +kotlin.targets.configureEach { + compilations.configureEach { + compileTaskProvider.get().compilerOptions { + freeCompilerArgs.add("-Xexpect-actual-classes") + } + } } \ No newline at end of file diff --git a/12-networking/projects/starter/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Database.android.kt b/12-networking/projects/starter/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Database.android.kt index 9872f353..43fab8bb 100644 --- a/12-networking/projects/starter/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Database.android.kt +++ b/12-networking/projects/starter/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Database.android.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Logger.android.kt b/12-networking/projects/starter/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Logger.android.kt index 5ffe7c44..e69c17d0 100644 --- a/12-networking/projects/starter/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Logger.android.kt +++ b/12-networking/projects/starter/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Logger.android.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Test.android.kt b/12-networking/projects/starter/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Test.android.kt index 0d643309..39447147 100644 --- a/12-networking/projects/starter/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Test.android.kt +++ b/12-networking/projects/starter/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Test.android.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/ServiceLocator.kt b/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/ServiceLocator.kt index c1ebeb21..d36d288b 100644 --- a/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/ServiceLocator.kt +++ b/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/ServiceLocator.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/domain/GetFeedData.kt b/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/domain/GetFeedData.kt index 30e08c9a..5b09f0f8 100644 --- a/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/domain/GetFeedData.kt +++ b/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/domain/GetFeedData.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/domain/cb/BookmarkData.kt b/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/domain/cb/BookmarkData.kt index 41f3cee7..325cfde4 100644 --- a/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/domain/cb/BookmarkData.kt +++ b/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/domain/cb/BookmarkData.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/domain/cb/FeedData.kt b/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/domain/cb/FeedData.kt index f8840287..02fc36dd 100644 --- a/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/domain/cb/FeedData.kt +++ b/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/domain/cb/FeedData.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/domain/dao/KodecoEntryDAO.kt b/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/domain/dao/KodecoEntryDAO.kt index 00e083cb..4237edb2 100644 --- a/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/domain/dao/KodecoEntryDAO.kt +++ b/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/domain/dao/KodecoEntryDAO.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Database.common.kt b/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Database.common.kt index 2900ec9d..d6561751 100644 --- a/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Database.common.kt +++ b/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Database.common.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Logger.common.kt b/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Logger.common.kt index a2fd9169..0315307a 100644 --- a/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Logger.common.kt +++ b/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Logger.common.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Test.common.kt b/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Test.common.kt index a3df1ada..37fa556c 100644 --- a/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Test.common.kt +++ b/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Test.common.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/BookmarkPresenter.kt b/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/BookmarkPresenter.kt index d57fa5e9..cdfec5a3 100644 --- a/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/BookmarkPresenter.kt +++ b/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/BookmarkPresenter.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/FeedPresenter.kt b/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/FeedPresenter.kt index 522c43b9..c28d9f34 100644 --- a/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/FeedPresenter.kt +++ b/12-networking/projects/starter/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/FeedPresenter.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -35,6 +35,7 @@ package com.kodeco.learn.presentation import com.kodeco.learn.data.model.KodecoContent +import com.kodeco.learn.data.model.KodecoEntry import com.kodeco.learn.domain.GetFeedData import kotlinx.serialization.json.Json @@ -50,6 +51,50 @@ private const val KODECO_CONTENT = "[" + "{\"platform\":\"growth\", \"url\":\"https://kodeco.com/professional-growth/feed\", \"image\":\"https://files.carolus.kodeco.com/gl22boss4ptciv7px3nnzcnct4ht?response_content_disposition=inline%3B+filename%3D%22progro.png%22%3B+filename%2A%3DUTF-8%27%27progro.png\"}" + "]" +private const val KODECO_ALL_FEED = """ + [ + { + "id": "https://www.kodeco.com/26244793-building-a-camera-app-with-swiftui-and-combine", + "link": "https://www.kodeco.com/26244793-building-a-camera-app-with-swiftui-and-combine", + "title": "Building a Camera App With SwiftUI and Combine [FREE]", + "summary":"Learn to natively build your own SwiftUI camera app using Combine and create fun filters using the power of Core Image.", + "updated": "2021-11-10T13:59:59Z" + }, + + { + "id": "https://www.kodeco.com/29045204-announcing-swiftui-by-tutorials-fourth-edition", + "link": "https://www.kodeco.com/29045204-announcing-swiftui-by-tutorials-fourth-edition", + "title": "Announcing SwiftUI by Tutorials, Fourth Edition! [FREE]", + "summary":"Build apps more efficiently with SwiftUI’s declarative approach and leave the old ways of imperative coding in the dust, with this freshly-updated book.", + "updated": "2021-11-10T13:44:43Z" + }, + + { + "id": "https://www.kodeco.com/books/swiftui-by-tutorialse", + "link": "https://www.kodeco.com/books/swiftui-by-tutorials", + "title": "SwiftUI by Tutorials [SUBSCRIBER]", + "summary":"Build fluid and engaging declarative UI for your apps — using less code — with SwiftUI!

SwiftUI by Tutorials is designed to help you learn how to transition from the “old way” of building your app UI with UIKit, to the “new way” of building responsive UI with modern declarative syntax with SwiftUI. This book is for readers who are comfortable building Swift apps, and want to make the exciting leap into building their app UI with modern, declarative code.

What is SwiftUI?

SwiftUI lets you build better apps, faster, and with less code. It’s a developer’s dream come true! With SwiftUI, you can design your user interfaces in a declarative way; instead of developing app interfaces in an imperative way, by coding all of the application state logic before time, you can instead define what your app’s UI should do in a particular state and let the underlying OS figure out how to do it. What’s more is that SwiftUI lets you build modern, responsive UI and animations for all Apple devices — not just iOS. So whether you’re building apps for iOS, watchOS, tvOS or any other Apple platform, you can use the same concise, natural language to describe your UI and have it look stunning — no matter where your code runs. In addition, SwiftUI’s built-in automatic support for things such as dark mode, localization and accessibility, along with Xcode 11 support for drag-and-drop design and instant preview makes it easier to build apps than ever before.

How is this book different than SwiftUI Apprentice?

Our other book on getting started with SwiftUI, SwiftUI Apprentice, is designed to teach new developers how to build iOS apps, using a SwiftUI-first approach. The goal of that book is to teach you fundamental development practices as you build out some fully-functional and great-looking apps! This book, SwiftUI by Tutorials, is designed for developers who have a solid background in iOS development, and are looking to make the leap from building apps with UIKit, to building apps with SwiftUI.", + "updated": "2021-11-10T00:00:00Z" + }, + + { + "id": "https://www.kodeco.com/26933987-flutter-ui-widgets", + "link": "https://www.kodeco.com/26933987-flutter-ui-widgets", + "title": "Flutter UI Widgets [SUBSCRIBER]", + "summary":"Explore commonly used UI widgets in Flutter and see how they relate to their native iOS and Android counterparts.", + "updated": "2021-11-09T00:00:00Z" + }, + + { + "id": "https://www.kodeco.com/26236685-shazamkit-tutorial-for-ios-getting-started", + "link": "https://www.kodeco.com/26236685-shazamkit-tutorial-for-ios-getting-started", + "title": "ShazamKit Tutorial for iOS: Getting Started [FREE]", + "summary":"Learn how to use ShazamKit to find information about specific audio recordings by matching a segment of that audio against a reference catalog of audio signatures.", + "updated": "2021-11-08T13:59:30Z" + } +] +""" + class FeedPresenter(private val feed: GetFeedData) { private val json = Json { ignoreUnknownKeys = true } @@ -57,4 +102,8 @@ class FeedPresenter(private val feed: GetFeedData) { val content: List by lazy { json.decodeFromString(KODECO_CONTENT) } + + val allFeeds: List by lazy { + json.decodeFromString(KODECO_ALL_FEED) + } } \ No newline at end of file diff --git a/12-networking/projects/starter/shared/src/commonTest/kotlin/SerializationTests.kt b/12-networking/projects/starter/shared/src/commonTest/kotlin/SerializationTests.kt index 5a2cfe8f..149a3135 100644 --- a/12-networking/projects/starter/shared/src/commonTest/kotlin/SerializationTests.kt +++ b/12-networking/projects/starter/shared/src/commonTest/kotlin/SerializationTests.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Database.ios.kt b/12-networking/projects/starter/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Database.ios.kt index 1328413f..073d4cfd 100644 --- a/12-networking/projects/starter/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Database.ios.kt +++ b/12-networking/projects/starter/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Database.ios.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Logger.ios.kt b/12-networking/projects/starter/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Logger.ios.kt index b8cb9781..4a0e1627 100644 --- a/12-networking/projects/starter/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Logger.ios.kt +++ b/12-networking/projects/starter/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Logger.ios.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Test.ios.kt b/12-networking/projects/starter/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Test.ios.kt index 0d643309..39447147 100644 --- a/12-networking/projects/starter/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Test.ios.kt +++ b/12-networking/projects/starter/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Test.ios.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Database.desktop.kt b/12-networking/projects/starter/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Database.jvm.kt similarity index 98% rename from 12-networking/projects/starter/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Database.desktop.kt rename to 12-networking/projects/starter/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Database.jvm.kt index 2e55f0e1..83304e3a 100644 --- a/12-networking/projects/starter/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Database.desktop.kt +++ b/12-networking/projects/starter/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Database.jvm.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Logger.desktop.kt b/12-networking/projects/starter/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Logger.jvm.kt similarity index 98% rename from 12-networking/projects/starter/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Logger.desktop.kt rename to 12-networking/projects/starter/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Logger.jvm.kt index e77f3495..e68ad692 100644 --- a/12-networking/projects/starter/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Logger.desktop.kt +++ b/12-networking/projects/starter/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Logger.jvm.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/starter/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Test.desktop.kt b/12-networking/projects/starter/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Test.jvm.kt similarity index 98% rename from 12-networking/projects/starter/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Test.desktop.kt rename to 12-networking/projects/starter/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Test.jvm.kt index 0d643309..39447147 100644 --- a/12-networking/projects/starter/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Test.desktop.kt +++ b/12-networking/projects/starter/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Test.jvm.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal From a82e371e3fda2f69f6640be6b5b9bd61f39e157c Mon Sep 17 00:00:00 2001 From: Carlos Mota Date: Mon, 3 Feb 2025 00:26:46 +0000 Subject: [PATCH 2/6] Updated final project --- 12-networking/projects/final/.gitignore | 3 +- .../final/androidApp/build.gradle.kts | 12 +- .../com/kodeco/learn/KodecoApplication.kt | 2 +- .../kodeco/learn/components/ImagePreview.kt | 2 +- .../java/com/kodeco/learn/ui/MainActivity.kt | 2 +- .../learn/ui/bookmark/BookmarkContent.kt | 10 +- .../learn/ui/bookmark/BookmarkViewModel.kt | 2 +- .../kodeco/learn/ui/common/EmptyContent.kt | 2 +- .../kodeco/learn/ui/common/EntryContent.kt | 12 +- .../com/kodeco/learn/ui/home/FeedViewModel.kt | 2 +- .../com/kodeco/learn/ui/home/HomeContent.kt | 8 +- .../kodeco/learn/ui/home/HomeSheetContent.kt | 12 +- .../kodeco/learn/ui/latest/LatestContent.kt | 2 +- .../learn/ui/main/BottomNavigationScreens.kt | 2 +- .../com/kodeco/learn/ui/main/MainBottomBar.kt | 2 +- .../com/kodeco/learn/ui/main/MainContent.kt | 10 +- .../com/kodeco/learn/ui/main/MainScreen.kt | 10 +- .../com/kodeco/learn/ui/main/MainTopAppBar.kt | 14 +-- .../kodeco/learn/ui/search/SearchContent.kt | 8 +- .../java/com/kodeco/learn/ui/theme/Color.kt | 2 +- .../java/com/kodeco/learn/ui/theme/Shape.kt | 2 +- .../java/com/kodeco/learn/ui/theme/Theme.kt | 47 ++++---- .../java/com/kodeco/learn/ui/theme/Type.kt | 36 +++++- .../main/java/com/kodeco/learn/utils/Utils.kt | 6 +- 12-networking/projects/final/build.gradle.kts | 7 +- .../final/desktopApp/build.gradle.kts | 50 +++++--- .../drawable}/ic_bookmarks.xml | 0 .../composeResources/drawable}/ic_brand.xml | 0 .../composeResources/drawable}/ic_home.xml | 0 .../composeResources/drawable}/ic_latest.xml | 0 .../composeResources/drawable}/ic_more.xml | 0 .../composeResources/drawable}/ic_search.xml | 0 .../composeResources}/font/opensans_bold.ttf | Bin .../font/opensans_extrabold.ttf | Bin .../composeResources}/font/opensans_light.ttf | Bin .../font/opensans_regular.ttf | Bin .../font/opensans_semibold.ttf | Bin .../composeResources/values/strings.xml | 36 ++++++ .../jvmMain/kotlin/com/kodeco/learn/Main.kt | 13 ++- .../kodeco/learn/components/ImagePreview.kt | 18 +-- .../learn/ui/bookmark/BookmarkContent.kt | 2 +- .../learn/ui/bookmark/BookmarkViewModel.kt | 6 +- .../kodeco/learn/ui/common/EmptyContent.kt | 2 +- .../kodeco/learn/ui/common/EntryContent.kt | 19 ++-- .../com/kodeco/learn/ui/home/FeedViewModel.kt | 6 +- .../com/kodeco/learn/ui/home/HomeContent.kt | 2 +- .../kodeco/learn/ui/home/HomeSheetContent.kt | 13 ++- .../kodeco/learn/ui/latest/LatestContent.kt | 2 +- .../learn/ui/main/BottomNavigationScreens.kt | 41 ++++--- .../com/kodeco/learn/ui/main/MainBottomBar.kt | 107 ------------------ .../com/kodeco/learn/ui/main/MainContent.kt | 59 +++++----- .../com/kodeco/learn/ui/main/MainScreen.kt | 67 ++++++----- .../com/kodeco/learn/ui/main/MainTopAppBar.kt | 22 ++-- .../kodeco/learn/ui/search/SearchContent.kt | 8 +- .../kotlin/com/kodeco/learn/ui/theme/Color.kt | 2 +- .../kotlin/com/kodeco/learn/ui/theme/Shape.kt | 2 +- .../kotlin/com/kodeco/learn/ui/theme/Theme.kt | 4 +- .../kotlin/com/kodeco/learn/ui/theme/Type.kt | 73 +++++++++--- .../kotlin/com/kodeco/learn/utils/Utils.kt | 6 +- .../projects/final/gradle.properties | 1 - .../projects/final/gradle/libs.versions.toml | 48 ++++---- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../iosApp/iosApp.xcodeproj/project.pbxproj | 14 +-- .../final/iosApp/iosApp/BookmarkView.swift | 3 +- .../final/iosApp/iosApp/ContentView.swift | 2 +- .../final/iosApp/iosApp/HomeView.swift | 2 +- .../iosApp/iosApp/KodecoEntryViewModel.swift | 2 +- .../final/iosApp/iosApp/LatestView.swift | 2 +- .../iosApp/iosApp/MainToolbarContent.swift | 2 +- .../final/iosApp/iosApp/SearchView.swift | 2 +- .../iosApp/iosApp/common/KodecoEntryRow.swift | 3 +- .../iosApp/extensions/BookmarkClient.swift | 2 +- .../iosApp/iosApp/extensions/FeedClient.swift | 2 +- .../projects/final/iosApp/iosApp/iOSApp.swift | 2 +- .../final/iosApp/iosApp/utils/Actions.swift | 2 +- .../final/iosApp/iosApp/utils/Utils.swift | 2 +- .../projects/final/settings.gradle.kts | 2 +- .../final/shared-dto/build.gradle.kts | 86 ++++++++------ .../learn/platform/Parcelable.android.kt | 4 +- .../com/kodeco/learn/data/KodecoSerializer.kt | 4 +- .../learn/data/model/GravatarContent.kt | 2 +- .../kodeco/learn/data/model/KodecoContent.kt | 2 +- .../kodeco/learn/data/model/KodecoEntry.kt | 4 +- .../learn/platform/Parcelable.common.kt | 2 +- .../kodeco/learn/platform/Parcelable.ios.kt | 2 +- ...arcelable.desktop.kt => Parcelable.jvm.kt} | 2 +- .../projects/final/shared/build.gradle.kts | 99 ++++++++-------- .../kodeco/learn/platform/Database.android.kt | 2 +- .../kodeco/learn/platform/Logger.android.kt | 2 +- .../com/kodeco/learn/platform/Test.android.kt | 2 +- .../kotlin/com/kodeco/learn/ServiceLocator.kt | 2 +- .../kotlin/com/kodeco/learn/Values.kt | 2 +- .../kotlin/com/kodeco/learn/data/FeedAPI.kt | 2 +- .../com/kodeco/learn/data/HttpClientLogger.kt | 2 +- .../com/kodeco/learn/domain/GetFeedData.kt | 2 +- .../kodeco/learn/domain/cb/BookmarkData.kt | 2 +- .../com/kodeco/learn/domain/cb/FeedData.kt | 2 +- .../kodeco/learn/domain/dao/KodecoEntryDAO.kt | 2 +- .../kodeco/learn/platform/Database.common.kt | 2 +- .../kodeco/learn/platform/Logger.common.kt | 2 +- .../com/kodeco/learn/platform/Test.common.kt | 2 +- .../learn/presentation/BookmarkPresenter.kt | 2 +- .../learn/presentation/FeedPresenter.kt | 52 ++++++++- .../src/commonTest/kotlin/NetworkTests.kt | 4 +- .../commonTest/kotlin/SerializationTests.kt | 2 +- .../com/kodeco/learn/platform/Database.ios.kt | 2 +- .../com/kodeco/learn/platform/Logger.ios.kt | 2 +- .../com/kodeco/learn/platform/Test.ios.kt | 2 +- .../kodeco/learn/platform/Database.jvm.kt} | 2 +- .../com/kodeco/learn/platform/Logger.jvm.kt} | 2 +- .../com/kodeco/learn/platform/Test.jvm.kt} | 2 +- 111 files changed, 653 insertions(+), 526 deletions(-) rename 12-networking/projects/final/desktopApp/src/{jvmMain/resources/images => commonMain/composeResources/drawable}/ic_bookmarks.xml (100%) rename 12-networking/projects/final/desktopApp/src/{jvmMain/resources/images => commonMain/composeResources/drawable}/ic_brand.xml (100%) rename 12-networking/projects/final/desktopApp/src/{jvmMain/resources/images => commonMain/composeResources/drawable}/ic_home.xml (100%) rename 12-networking/projects/final/desktopApp/src/{jvmMain/resources/images => commonMain/composeResources/drawable}/ic_latest.xml (100%) rename 12-networking/projects/final/desktopApp/src/{jvmMain/resources/images => commonMain/composeResources/drawable}/ic_more.xml (100%) rename 12-networking/projects/final/desktopApp/src/{jvmMain/resources/images => commonMain/composeResources/drawable}/ic_search.xml (100%) rename 12-networking/projects/final/desktopApp/src/{jvmMain/resources => commonMain/composeResources}/font/opensans_bold.ttf (100%) rename 12-networking/projects/final/desktopApp/src/{jvmMain/resources => commonMain/composeResources}/font/opensans_extrabold.ttf (100%) rename 12-networking/projects/final/desktopApp/src/{jvmMain/resources => commonMain/composeResources}/font/opensans_light.ttf (100%) rename 12-networking/projects/final/desktopApp/src/{jvmMain/resources => commonMain/composeResources}/font/opensans_regular.ttf (100%) rename 12-networking/projects/final/desktopApp/src/{jvmMain/resources => commonMain/composeResources}/font/opensans_semibold.ttf (100%) create mode 100644 12-networking/projects/final/desktopApp/src/commonMain/composeResources/values/strings.xml delete mode 100644 12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainBottomBar.kt rename 12-networking/projects/final/shared-dto/src/jvmMain/kotlin/com/kodeco/learn/platform/{Parcelable.desktop.kt => Parcelable.jvm.kt} (98%) rename 12-networking/projects/final/shared/src/{desktopMain/kotlin/com/kodeco/learn/platform/Database.desktop.kt => jvmMain/kotlin/com/kodeco/learn/platform/Database.jvm.kt} (98%) rename 12-networking/projects/final/shared/src/{desktopMain/kotlin/com/kodeco/learn/platform/Logger.desktop.kt => jvmMain/kotlin/com/kodeco/learn/platform/Logger.jvm.kt} (98%) rename 12-networking/projects/final/shared/src/{desktopMain/kotlin/com/kodeco/learn/platform/Test.desktop.kt => jvmMain/kotlin/com/kodeco/learn/platform/Test.jvm.kt} (98%) diff --git a/12-networking/projects/final/.gitignore b/12-networking/projects/final/.gitignore index b1bb87f1..90d16852 100644 --- a/12-networking/projects/final/.gitignore +++ b/12-networking/projects/final/.gitignore @@ -15,8 +15,9 @@ bin/ gen/ out/ -# Gradle files +# Project files .gradle/ +.kotlin/ build/ androidApp/build desktopApp/build diff --git a/12-networking/projects/final/androidApp/build.gradle.kts b/12-networking/projects/final/androidApp/build.gradle.kts index 820caca5..9b6d2be3 100644 --- a/12-networking/projects/final/androidApp/build.gradle.kts +++ b/12-networking/projects/final/androidApp/build.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -35,6 +35,8 @@ plugins { id("com.android.application") kotlin("android") + + alias(libs.plugins.jetbrains.compose.compiler) } dependencies { @@ -63,8 +65,8 @@ android { applicationId = "com.kodeco.learn" minSdk = libs.versions.android.sdk.min.get().toInt() targetSdk = libs.versions.android.sdk.target.get().toInt() - versionCode = 2 - versionName = "2.0" + versionCode = 3 + versionName = "3.0" } buildTypes { @@ -86,10 +88,6 @@ android { jvmTarget = "17" } - composeOptions { - kotlinCompilerExtensionVersion = libs.versions.android.compose.compiler.get() - } - packaging { resources { excludes += "/META-INF/{AL2.0,LGPL2.1}" diff --git a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/KodecoApplication.kt b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/KodecoApplication.kt index 1dbfd1c6..bb5174e2 100644 --- a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/KodecoApplication.kt +++ b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/KodecoApplication.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/components/ImagePreview.kt b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/components/ImagePreview.kt index 9a33e6c5..b404d47e 100644 --- a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/components/ImagePreview.kt +++ b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/components/ImagePreview.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/MainActivity.kt b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/MainActivity.kt index 4d31c99a..7d616ec5 100644 --- a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/MainActivity.kt +++ b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/MainActivity.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/bookmark/BookmarkContent.kt b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/bookmark/BookmarkContent.kt index fb81f218..205fd1f1 100644 --- a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/bookmark/BookmarkContent.kt +++ b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/bookmark/BookmarkContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -37,8 +37,8 @@ package com.kodeco.learn.ui.bookmark import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.material.BottomSheetScaffoldState -import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.State @@ -53,7 +53,7 @@ import kotlinx.coroutines.CoroutineScope private const val TAG = "BookmarkContent" -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun BookmarkContent( selected: MutableState, @@ -80,7 +80,7 @@ fun BookmarkContent( } } -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun AddBookmarks( selected: MutableState, diff --git a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/bookmark/BookmarkViewModel.kt b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/bookmark/BookmarkViewModel.kt index b1b885a7..75b939f8 100644 --- a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/bookmark/BookmarkViewModel.kt +++ b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/bookmark/BookmarkViewModel.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/common/EmptyContent.kt b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/common/EmptyContent.kt index bd221c2d..ba7b331f 100644 --- a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/common/EmptyContent.kt +++ b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/common/EmptyContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/common/EntryContent.kt b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/common/EntryContent.kt index 28ea5f76..5107a643 100644 --- a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/common/EntryContent.kt +++ b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/common/EntryContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -45,9 +45,9 @@ 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.BottomSheetScaffoldState -import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material3.Divider +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -69,7 +69,7 @@ import kotlinx.coroutines.launch private const val TAG = "EntryContent" -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun AddEntryContent( item: KodecoEntry, @@ -169,7 +169,7 @@ fun AddEntryContent( Spacer(modifier = Modifier.height(16.dp)) if (divider) { - Divider( + HorizontalDivider( modifier = Modifier.fillMaxWidth(), thickness = 1.dp ) diff --git a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/home/FeedViewModel.kt b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/home/FeedViewModel.kt index 4b527ad3..ec3a5534 100644 --- a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/home/FeedViewModel.kt +++ b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/home/FeedViewModel.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/home/HomeContent.kt b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/home/HomeContent.kt index 99dd0f0d..a1a30553 100644 --- a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/home/HomeContent.kt +++ b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/home/HomeContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -47,8 +47,8 @@ import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.BottomSheetScaffoldState -import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState @@ -69,7 +69,7 @@ import kotlinx.coroutines.CoroutineScope private const val TAG = "HomeContent" -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun HomeContent( selected: MutableState, diff --git a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/home/HomeSheetContent.kt b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/home/HomeSheetContent.kt index 88890b61..d4d1a53a 100644 --- a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/home/HomeSheetContent.kt +++ b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/home/HomeSheetContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -39,8 +39,8 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.material.BottomSheetScaffoldState -import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState @@ -55,7 +55,7 @@ import kotlinx.coroutines.launch private const val TAG = "HomeSheetContent" -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun HomeSheetContent( item: MutableState, @@ -76,7 +76,7 @@ fun HomeSheetContent( .fillMaxWidth() .clickable { coroutineScope.launch { - bottomSheetScaffoldState.bottomSheetState.collapse() + bottomSheetScaffoldState.bottomSheetState.hide() } onUpdateBookmark(item.value) @@ -102,7 +102,7 @@ fun HomeSheetContent( .fillMaxWidth() .clickable { coroutineScope.launch { - bottomSheetScaffoldState.bottomSheetState.collapse() + bottomSheetScaffoldState.bottomSheetState.hide() } onShareAsLink(item.value) diff --git a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/latest/LatestContent.kt b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/latest/LatestContent.kt index 32045322..382e52a5 100644 --- a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/latest/LatestContent.kt +++ b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/latest/LatestContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/main/BottomNavigationScreens.kt b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/main/BottomNavigationScreens.kt index 8e3f6ebf..1e97ea99 100644 --- a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/main/BottomNavigationScreens.kt +++ b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/main/BottomNavigationScreens.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/main/MainBottomBar.kt b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/main/MainBottomBar.kt index 94a16670..69c8dde6 100644 --- a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/main/MainBottomBar.kt +++ b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/main/MainBottomBar.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/main/MainContent.kt b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/main/MainContent.kt index ebecd8e2..da09e23f 100644 --- a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/main/MainContent.kt +++ b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/main/MainContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -35,8 +35,8 @@ package com.kodeco.learn.ui.main import androidx.compose.foundation.layout.Column -import androidx.compose.material.BottomSheetScaffoldState -import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.State @@ -54,7 +54,7 @@ import kotlinx.coroutines.CoroutineScope private val DEFAULT_SCREEN = BottomNavigationScreens.Home -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun MainContent( navController: NavHostController, @@ -79,7 +79,7 @@ fun MainContent( } } -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable private fun MainScreenNavigationConfigurations( navController: NavHostController, diff --git a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/main/MainScreen.kt b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/main/MainScreen.kt index 66964f83..4f17901a 100644 --- a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/main/MainScreen.kt +++ b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/main/MainScreen.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -37,9 +37,9 @@ package com.kodeco.learn.ui.main import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.BottomSheetScaffold -import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.rememberBottomSheetScaffoldState +import androidx.compose.material3.BottomSheetScaffold +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.rememberBottomSheetScaffoldState import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState @@ -58,7 +58,7 @@ import com.kodeco.learn.ui.home.HomeSheetContent private lateinit var selected: MutableState -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun MainScreen( profile: GravatarEntry?, diff --git a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/main/MainTopAppBar.kt b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/main/MainTopAppBar.kt index 15e0d6e5..65e05449 100644 --- a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/main/MainTopAppBar.kt +++ b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/main/MainTopAppBar.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -71,15 +71,15 @@ fun MainTopAppBar( val avatarUrl = profile?.thumbnailUrl if (avatarUrl == null) { Icon( - imageVector = Icons.Filled.Person, - contentDescription = stringResource(R.string.description_profile) + imageVector = Icons.Filled.Person, + contentDescription = stringResource(R.string.description_profile) ) } else { AddImagePreview( - url = avatarUrl, - modifier = Modifier - .clip(CircleShape) - .size(25.dp) + url = avatarUrl, + modifier = Modifier + .clip(CircleShape) + .size(25.dp) ) } } diff --git a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/search/SearchContent.kt b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/search/SearchContent.kt index f0685e21..137399c8 100644 --- a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/search/SearchContent.kt +++ b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/search/SearchContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,8 +38,8 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.material.BottomSheetScaffoldState -import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Surface @@ -63,7 +63,7 @@ import kotlinx.coroutines.CoroutineScope private const val TAG = "SearchContent" -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun SearchContent( selected: MutableState, diff --git a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/theme/Color.kt b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/theme/Color.kt index a594ad49..2e781c25 100644 --- a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/theme/Color.kt +++ b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/theme/Color.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/theme/Shape.kt b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/theme/Shape.kt index 8964a873..329ab7f5 100644 --- a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/theme/Shape.kt +++ b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/theme/Shape.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/theme/Theme.kt b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/theme/Theme.kt index 0fd73cb6..b59eedd4 100644 --- a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/theme/Theme.kt +++ b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/theme/Theme.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -35,6 +35,7 @@ package com.kodeco.learn.ui.theme import android.app.Activity +import android.os.Build import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.material3.MaterialTheme import androidx.compose.material3.darkColorScheme @@ -46,27 +47,28 @@ import androidx.compose.ui.platform.LocalView import androidx.core.view.WindowCompat private val DarkColorScheme = darkColorScheme( - primary = darkTextPrimary, - surface = darkBackground, - onSurfaceVariant = darkTextPrimary, - background = darkBackground, - secondaryContainer = darkSecondaryContainer, - onSecondaryContainer = darkBackground + primary = darkTextPrimary, + surface = darkBackground, + onSurfaceVariant = darkTextPrimary, + background = darkBackground, + secondaryContainer = darkSecondaryContainer, + onSecondaryContainer = darkBackground ) private val LightColorScheme = lightColorScheme( - primary = lightTextPrimary, - surface = lightBackground, - onSurfaceVariant = lightTextPrimary, - background = lightBackground, - secondaryContainer = lightSecondaryContainer, - onSecondaryContainer = lightBackground + primary = lightTextPrimary, + surface = lightBackground, + onSurfaceVariant = lightTextPrimary, + background = lightBackground, + secondaryContainer = lightSecondaryContainer, + onSecondaryContainer = lightBackground ) +@Suppress("DEPRECATION") @Composable fun KodecoTheme( - darkTheme: Boolean = isSystemInDarkTheme(), - content: @Composable () -> Unit + darkTheme: Boolean = isSystemInDarkTheme(), + content: @Composable () -> Unit ) { val colorScheme = when { darkTheme -> DarkColorScheme @@ -77,14 +79,21 @@ fun KodecoTheme( if (!view.isInEditMode) { SideEffect { val window = (view.context as Activity).window - window.statusBarColor = colorScheme.surface.toArgb() + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) { + window.decorView.setOnApplyWindowInsetsListener { view, insets -> + view.setBackgroundColor(colorScheme.surface.toArgb()) + insets + } + } else { + window.statusBarColor = colorScheme.surface.toArgb() + } WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !darkTheme } } MaterialTheme( - colorScheme = colorScheme, - typography = Typography, - content = content + colorScheme = colorScheme, + typography = Typography, + content = content ) } \ No newline at end of file diff --git a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/theme/Type.kt b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/theme/Type.kt index 5c500810..a5ef1f0b 100644 --- a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/theme/Type.kt +++ b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/theme/Type.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -90,5 +90,39 @@ val Typography = Typography( bodySmall = TextStyle( fontFamily = OpenSansFontFamily, fontSize = fontSizeSmall + ), + + titleLarge = TextStyle( + fontFamily = OpenSansFontFamily, + fontWeight = FontWeight.Normal, + fontSize = fontSizeBig + ), + + titleMedium = TextStyle( + fontFamily = OpenSansFontFamily, + fontWeight = FontWeight.Bold, + fontSize = fontSizeSmall + ), + + titleSmall = TextStyle( + fontFamily = OpenSansFontFamily, + fontSize = fontSizeSmall + ), + + labelLarge = TextStyle( + fontFamily = OpenSansFontFamily, + fontWeight = FontWeight.Normal, + fontSize = fontSizeBig + ), + + labelMedium = TextStyle( + fontFamily = OpenSansFontFamily, + fontWeight = FontWeight.Bold, + fontSize = fontSizeSmall + ), + + labelSmall = TextStyle( + fontFamily = OpenSansFontFamily, + fontSize = fontSizeSmall ) ) \ No newline at end of file diff --git a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/utils/Utils.kt b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/utils/Utils.kt index ce66defb..b0cec1fc 100644 --- a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/utils/Utils.kt +++ b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/utils/Utils.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -36,7 +36,7 @@ package com.kodeco.learn.utils import android.annotation.SuppressLint import com.kodeco.learn.platform.Logger -import kotlinx.datetime.toInstant +import kotlinx.datetime.Instant import java.text.SimpleDateFormat import java.util.* @@ -47,7 +47,7 @@ private val simpleDateFormat = SimpleDateFormat("yyyy/MM/dd", Locale.getDefault( fun converterIso8601ToReadableDate(date: String): String { return try { - val instant = date.toInstant() + val instant = Instant.parse(date) val millis = Date(instant.toEpochMilliseconds()) return simpleDateFormat.format(millis) } catch (e: Exception) { diff --git a/12-networking/projects/final/build.gradle.kts b/12-networking/projects/final/build.gradle.kts index f9602113..8d1115ba 100644 --- a/12-networking/projects/final/build.gradle.kts +++ b/12-networking/projects/final/build.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,15 +32,14 @@ * THE SOFTWARE. */ -// Top-level build file where you can add configuration options common to all sub-projects/modules. -@Suppress("DSL_SCOPE_VIOLATION") plugins { alias(libs.plugins.android.application) apply false alias(libs.plugins.android.library) apply false + alias(libs.plugins.jetbrains.compose.compiler) apply false alias(libs.plugins.jetbrains.kotlin) apply false alias(libs.plugins.jetbrains.kotlin.multiplatform) apply false - alias(libs.plugins.jetbrains.kotlin.parcelize) apply false alias(libs.plugins.jetbrains.kotlin.serialization) apply false + alias(libs.plugins.jetbrains.kotlin.parcelize) apply false alias(libs.plugins.cash.sqldelight) apply false } diff --git a/12-networking/projects/final/desktopApp/build.gradle.kts b/12-networking/projects/final/desktopApp/build.gradle.kts index 1515c5ed..40b47c25 100644 --- a/12-networking/projects/final/desktopApp/build.gradle.kts +++ b/12-networking/projects/final/desktopApp/build.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -33,41 +33,50 @@ */ import org.jetbrains.compose.desktop.application.dsl.TargetFormat +import org.jetbrains.kotlin.gradle.dsl.JvmTarget plugins { alias(libs.plugins.jetbrains.kotlin.multiplatform) + alias(libs.plugins.jetbrains.compose) + alias(libs.plugins.jetbrains.compose.compiler) } kotlin { jvm { compilations.all { - kotlinOptions.jvmTarget = "17" + compileTaskProvider.configure { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_17) + } + } } } sourceSets { - getByName("jvmMain") { - dependencies { - implementation(project(":shared")) + commonMain.dependencies { + implementation(compose.components.resources) + } - implementation(compose.desktop.currentOs) + jvmMain.dependencies { + implementation(project(":shared")) - implementation(compose.foundation) - implementation(compose.runtime) - implementation(compose.foundation) - implementation(compose.material) - implementation(compose.material3) - implementation(compose.ui) + implementation(compose.desktop.currentOs) - implementation(libs.kotlinx.datetime) + implementation(compose.foundation) + implementation(compose.runtime) + implementation(compose.foundation) + implementation(compose.material) + implementation(compose.material3) + implementation(compose.material3AdaptiveNavigationSuite) + implementation(compose.ui) - implementation(libs.image.loader) + implementation(libs.kotlinx.datetime) - implementation(libs.precompose) - implementation(libs.precompose.viewmodel) - } + implementation(libs.image.loader) + + implementation(libs.jetbrains.compose.lifecycle) } } } @@ -79,7 +88,7 @@ compose.desktop { nativeDistributions { targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb) packageName = "learn" - packageVersion = "2.0.0" + packageVersion = "3.0.0" val resources = project.layout.projectDirectory.dir("src/jvmMain/resources") appResourcesRootDir.set(resources) @@ -98,4 +107,9 @@ compose.desktop { } } } +} + +compose.resources { + publicResClass = true + packageOfResClass = "com.kodeco.learn.resources" } \ No newline at end of file diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/resources/images/ic_bookmarks.xml b/12-networking/projects/final/desktopApp/src/commonMain/composeResources/drawable/ic_bookmarks.xml similarity index 100% rename from 12-networking/projects/final/desktopApp/src/jvmMain/resources/images/ic_bookmarks.xml rename to 12-networking/projects/final/desktopApp/src/commonMain/composeResources/drawable/ic_bookmarks.xml diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/resources/images/ic_brand.xml b/12-networking/projects/final/desktopApp/src/commonMain/composeResources/drawable/ic_brand.xml similarity index 100% rename from 12-networking/projects/final/desktopApp/src/jvmMain/resources/images/ic_brand.xml rename to 12-networking/projects/final/desktopApp/src/commonMain/composeResources/drawable/ic_brand.xml diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/resources/images/ic_home.xml b/12-networking/projects/final/desktopApp/src/commonMain/composeResources/drawable/ic_home.xml similarity index 100% rename from 12-networking/projects/final/desktopApp/src/jvmMain/resources/images/ic_home.xml rename to 12-networking/projects/final/desktopApp/src/commonMain/composeResources/drawable/ic_home.xml diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/resources/images/ic_latest.xml b/12-networking/projects/final/desktopApp/src/commonMain/composeResources/drawable/ic_latest.xml similarity index 100% rename from 12-networking/projects/final/desktopApp/src/jvmMain/resources/images/ic_latest.xml rename to 12-networking/projects/final/desktopApp/src/commonMain/composeResources/drawable/ic_latest.xml diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/resources/images/ic_more.xml b/12-networking/projects/final/desktopApp/src/commonMain/composeResources/drawable/ic_more.xml similarity index 100% rename from 12-networking/projects/final/desktopApp/src/jvmMain/resources/images/ic_more.xml rename to 12-networking/projects/final/desktopApp/src/commonMain/composeResources/drawable/ic_more.xml diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/resources/images/ic_search.xml b/12-networking/projects/final/desktopApp/src/commonMain/composeResources/drawable/ic_search.xml similarity index 100% rename from 12-networking/projects/final/desktopApp/src/jvmMain/resources/images/ic_search.xml rename to 12-networking/projects/final/desktopApp/src/commonMain/composeResources/drawable/ic_search.xml diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/resources/font/opensans_bold.ttf b/12-networking/projects/final/desktopApp/src/commonMain/composeResources/font/opensans_bold.ttf similarity index 100% rename from 12-networking/projects/final/desktopApp/src/jvmMain/resources/font/opensans_bold.ttf rename to 12-networking/projects/final/desktopApp/src/commonMain/composeResources/font/opensans_bold.ttf diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/resources/font/opensans_extrabold.ttf b/12-networking/projects/final/desktopApp/src/commonMain/composeResources/font/opensans_extrabold.ttf similarity index 100% rename from 12-networking/projects/final/desktopApp/src/jvmMain/resources/font/opensans_extrabold.ttf rename to 12-networking/projects/final/desktopApp/src/commonMain/composeResources/font/opensans_extrabold.ttf diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/resources/font/opensans_light.ttf b/12-networking/projects/final/desktopApp/src/commonMain/composeResources/font/opensans_light.ttf similarity index 100% rename from 12-networking/projects/final/desktopApp/src/jvmMain/resources/font/opensans_light.ttf rename to 12-networking/projects/final/desktopApp/src/commonMain/composeResources/font/opensans_light.ttf diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/resources/font/opensans_regular.ttf b/12-networking/projects/final/desktopApp/src/commonMain/composeResources/font/opensans_regular.ttf similarity index 100% rename from 12-networking/projects/final/desktopApp/src/jvmMain/resources/font/opensans_regular.ttf rename to 12-networking/projects/final/desktopApp/src/commonMain/composeResources/font/opensans_regular.ttf diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/resources/font/opensans_semibold.ttf b/12-networking/projects/final/desktopApp/src/commonMain/composeResources/font/opensans_semibold.ttf similarity index 100% rename from 12-networking/projects/final/desktopApp/src/jvmMain/resources/font/opensans_semibold.ttf rename to 12-networking/projects/final/desktopApp/src/commonMain/composeResources/font/opensans_semibold.ttf diff --git a/12-networking/projects/final/desktopApp/src/commonMain/composeResources/values/strings.xml b/12-networking/projects/final/desktopApp/src/commonMain/composeResources/values/strings.xml new file mode 100644 index 00000000..c9820921 --- /dev/null +++ b/12-networking/projects/final/desktopApp/src/commonMain/composeResources/values/strings.xml @@ -0,0 +1,36 @@ + + learn + Kodeco + + + Home + Bookmark + Latest + Search + + + You currently don\'t have any bookmark. + Loading… + + + Search + + + Hello %s! + + Add to bookmarks + Remove from bookmarks + Share as link + Hey! Check out this article that I\'ve just found: %s. + + Added to bookmarks! + Removed from bookmarks + + + Search for a specific article + Feed icon + More actions + Image preview + Unable to load image preview + User profile + \ No newline at end of file diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/Main.kt b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/Main.kt index 7b46d332..8bf0bd83 100644 --- a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/Main.kt +++ b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/Main.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,16 +38,19 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material.Surface import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Window import androidx.compose.ui.window.application import androidx.compose.ui.window.rememberWindowState +import androidx.lifecycle.viewmodel.compose.viewModel import com.kodeco.learn.data.model.KodecoEntry import com.kodeco.learn.platform.Logger +import com.kodeco.learn.resources.Res +import com.kodeco.learn.resources.app_name import com.kodeco.learn.ui.bookmark.BookmarkViewModel import com.kodeco.learn.ui.home.FeedViewModel import com.kodeco.learn.ui.main.MainScreen import com.kodeco.learn.ui.theme.KodecoTheme -import moe.tlaster.precompose.PreComposeWindow -import moe.tlaster.precompose.viewmodel.viewModel +import org.jetbrains.compose.resources.stringResource import java.awt.Desktop import java.net.URI @@ -61,10 +64,10 @@ fun main() { application { val windowState = rememberWindowState(width = 460.dp, height = 900.dp) - PreComposeWindow( + Window( onCloseRequest = ::exitApplication, state = windowState, - title = "learn" + title = stringResource(Res.string.app_name) ) { bookmarkViewModel = viewModel { BookmarkViewModel() diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/components/ImagePreview.kt b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/components/ImagePreview.kt index 5aa04a0a..21065c38 100644 --- a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/components/ImagePreview.kt +++ b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/components/ImagePreview.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -45,9 +45,14 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.res.painterResource import com.kodeco.learn.platform.Logger +import com.kodeco.learn.resources.Res +import com.kodeco.learn.resources.description_preview +import com.kodeco.learn.resources.description_preview_error +import com.kodeco.learn.resources.ic_brand import com.seiko.imageloader.rememberImagePainter +import org.jetbrains.compose.resources.painterResource +import org.jetbrains.compose.resources.stringResource private const val TAG = "ImagePreview" @@ -65,8 +70,7 @@ fun AddImagePreview( } else { Box { - - val resource = painterResource("images/ic_brand.xml") + val resource = painterResource(Res.drawable.ic_brand) val painter = rememberImagePainter( url = url, @@ -77,7 +81,7 @@ fun AddImagePreview( Image( painter = painter, contentScale = ContentScale.Crop, - contentDescription = "Image preview", + contentDescription = stringResource(Res.string.description_preview), modifier = modifier ) } @@ -100,8 +104,8 @@ fun AddImagePreviewEmpty( color = Color.Transparent ) { - val resource = painterResource("images/ic_brand.xml") - val description = "Unable to load image preview" + val resource = painterResource(Res.drawable.ic_brand) + val description = stringResource(Res.string.description_preview_error) Column( horizontalAlignment = Alignment.CenterHorizontally, diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/bookmark/BookmarkContent.kt b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/bookmark/BookmarkContent.kt index b4812196..1c4f50c9 100644 --- a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/bookmark/BookmarkContent.kt +++ b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/bookmark/BookmarkContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/bookmark/BookmarkViewModel.kt b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/bookmark/BookmarkViewModel.kt index 28b42d5b..4a9a10b6 100644 --- a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/bookmark/BookmarkViewModel.kt +++ b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/bookmark/BookmarkViewModel.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -36,6 +36,8 @@ package com.kodeco.learn.ui.bookmark import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope import com.kodeco.learn.ServiceLocator import com.kodeco.learn.data.model.KodecoEntry import com.kodeco.learn.domain.cb.BookmarkData @@ -43,8 +45,6 @@ import com.kodeco.learn.platform.Logger import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import moe.tlaster.precompose.viewmodel.ViewModel -import moe.tlaster.precompose.viewmodel.viewModelScope private const val TAG = "BookmarkViewModel" diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/common/EmptyContent.kt b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/common/EmptyContent.kt index bd221c2d..ba7b331f 100644 --- a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/common/EmptyContent.kt +++ b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/common/EmptyContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/common/EntryContent.kt b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/common/EntryContent.kt index 8258206a..f00ea9a8 100644 --- a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/common/EntryContent.kt +++ b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/common/EntryContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -47,7 +47,7 @@ import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.BottomSheetScaffoldState import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material3.Divider +import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -55,15 +55,20 @@ import androidx.compose.runtime.MutableState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip -import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.kodeco.learn.components.AddImagePreview import com.kodeco.learn.data.model.KodecoEntry import com.kodeco.learn.platform.Logger +import com.kodeco.learn.resources.Res +import com.kodeco.learn.resources.app_kodeco +import com.kodeco.learn.resources.description_more +import com.kodeco.learn.resources.ic_more import com.kodeco.learn.utils.converterIso8601ToReadableDate import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch +import org.jetbrains.compose.resources.painterResource +import org.jetbrains.compose.resources.stringResource private const val TAG = "EntryContent" @@ -118,7 +123,7 @@ fun AddEntryContent( ) { Text( - text = "Kodeco" + text = stringResource(Res.string.app_kodeco) ) Text( @@ -132,8 +137,8 @@ fun AddEntryContent( horizontalArrangement = Arrangement.End ) { - val resource = painterResource("images/ic_more.xml") - val description = "More actions" + val resource = painterResource(Res.drawable.ic_more) + val description = stringResource(Res.string.description_more) Icon( painter = resource, @@ -167,7 +172,7 @@ fun AddEntryContent( Spacer(modifier = Modifier.height(16.dp)) if (divider) { - Divider( + HorizontalDivider( modifier = Modifier.fillMaxWidth(), thickness = 1.dp ) diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/FeedViewModel.kt b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/FeedViewModel.kt index dc420fc0..bef56617 100644 --- a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/FeedViewModel.kt +++ b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/FeedViewModel.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,6 +38,8 @@ import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateMapOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.snapshots.SnapshotStateMap +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope import com.kodeco.learn.ServiceLocator import com.kodeco.learn.data.model.GravatarEntry import com.kodeco.learn.data.model.KodecoEntry @@ -45,8 +47,6 @@ import com.kodeco.learn.data.model.PLATFORM import com.kodeco.learn.domain.cb.FeedData import com.kodeco.learn.platform.Logger import kotlinx.coroutines.launch -import moe.tlaster.precompose.viewmodel.ViewModel -import moe.tlaster.precompose.viewmodel.viewModelScope private const val TAG = "FeedViewModel" diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/HomeContent.kt b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/HomeContent.kt index 99dd0f0d..30a13cbc 100644 --- a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/HomeContent.kt +++ b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/HomeContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/HomeSheetContent.kt b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/HomeSheetContent.kt index 3dcc478c..454cc983 100644 --- a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/HomeSheetContent.kt +++ b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/HomeSheetContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -48,8 +48,13 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.kodeco.learn.data.model.KodecoEntry import com.kodeco.learn.platform.Logger +import com.kodeco.learn.resources.Res +import com.kodeco.learn.resources.action_add_bookmarks +import com.kodeco.learn.resources.action_remove_bookmarks +import com.kodeco.learn.resources.action_share_link import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch +import org.jetbrains.compose.resources.stringResource private const val TAG = "HomeSheetContent" @@ -82,9 +87,9 @@ fun HomeSheetContent( ) { val text = if (item.value.bookmarked) { - "Remove from bookmarks" + stringResource(Res.string.action_remove_bookmarks) } else { - "Add to bookmarks" + stringResource(Res.string.action_add_bookmarks) } Text( @@ -107,7 +112,7 @@ fun HomeSheetContent( } ) { Text( - text = "Share as link", + text = stringResource(Res.string.action_share_link), modifier = Modifier .fillMaxWidth() .padding(start = 16.dp, top = 12.dp, end = 16.dp, bottom = 24.dp) diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/latest/LatestContent.kt b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/latest/LatestContent.kt index fa2e9f5f..f88cd468 100644 --- a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/latest/LatestContent.kt +++ b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/latest/LatestContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/BottomNavigationScreens.kt b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/BottomNavigationScreens.kt index 14220282..83b09871 100644 --- a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/BottomNavigationScreens.kt +++ b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/BottomNavigationScreens.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -36,54 +36,65 @@ package com.kodeco.learn.ui.main import androidx.compose.material3.Icon import androidx.compose.runtime.Composable -import androidx.compose.ui.res.painterResource +import com.kodeco.learn.resources.Res +import com.kodeco.learn.resources.ic_bookmarks +import com.kodeco.learn.resources.ic_home +import com.kodeco.learn.resources.ic_latest +import com.kodeco.learn.resources.ic_search +import com.kodeco.learn.resources.navigation_bookmark +import com.kodeco.learn.resources.navigation_home +import com.kodeco.learn.resources.navigation_latest +import com.kodeco.learn.resources.navigation_search +import org.jetbrains.compose.resources.StringResource +import org.jetbrains.compose.resources.painterResource +import org.jetbrains.compose.resources.stringResource sealed class BottomNavigationScreens( val route: String, - val title: String, + val title: StringResource, val icon: @Composable () -> Unit ) { data object Home : BottomNavigationScreens( route = "Home", - title = "Home", + title = Res.string.navigation_home, icon = { Icon( - painter = painterResource("images/ic_home.xml"), - contentDescription = "Home" + painter = painterResource(Res.drawable.ic_home), + contentDescription = stringResource(Res.string.navigation_home) ) } ) data object Bookmark : BottomNavigationScreens( route = "Bookmark", - title = "Bookmark", + title = Res.string.navigation_bookmark, icon = { Icon( - painter = painterResource("images/ic_bookmarks.xml"), - contentDescription = "Bookmark" + painter = painterResource(Res.drawable.ic_bookmarks), + contentDescription = stringResource(Res.string.navigation_bookmark) ) } ) data object Latest : BottomNavigationScreens( route = "Latest", - title = "Latest", + title = Res.string.navigation_latest, icon = { Icon( - painter = painterResource("images/ic_latest.xml"), - contentDescription = "Latest" + painter = painterResource(Res.drawable.ic_latest), + contentDescription = stringResource(Res.string.navigation_latest) ) } ) data object Search : BottomNavigationScreens( route = "Search", - title = "Search", + title = Res.string.navigation_search, icon = { Icon( - painter = painterResource("images/ic_search.xml"), - contentDescription = "Search" + painter = painterResource(Res.drawable.ic_search), + contentDescription = stringResource(Res.string.navigation_search) ) } ) diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainBottomBar.kt b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainBottomBar.kt deleted file mode 100644 index 9a0aa349..00000000 --- a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainBottomBar.kt +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2023 Kodeco Inc - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, - * distribute, sublicense, create a derivative work, and/or sell copies of the - * Software in any work that is designed, intended, or marketed for pedagogical or - * instructional purposes related to programming, coding, application development, - * or information technology. Permission for such use, copying, modification, - * merger, publication, distribution, sublicensing, creation of derivative works, - * or sale is expressly withheld. - * - * This project and source code may use libraries or frameworks that are - * released under various Open-Source licenses. Use of those libraries and - * frameworks are governed by their own individual licenses. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.kodeco.learn.ui.main - -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.material3.BottomAppBar -import androidx.compose.material3.NavigationBarItem -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState -import androidx.compose.runtime.mutableIntStateOf -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import moe.tlaster.precompose.navigation.Navigator - -private lateinit var selectedIndex: MutableState - -@Composable -fun MainBottomBar( - navController: Navigator, - items: List -) { - - Column { - Row( - modifier = Modifier - .fillMaxWidth() - .height(1.dp) - ) {} - - AppBottomNavigation( - navController = navController, - items = items - ) - } -} - -@Composable -private fun AppBottomNavigation( - navController: Navigator, - items: List -) { - BottomAppBar { - - selectedIndex = remember { mutableIntStateOf(0) } - - items.forEachIndexed { index, screen -> - - val isSelected = selectedIndex.value == index - - NavigationBarItem( - icon = { - screen.icon() - }, - label = { - Text( - text = screen.title - ) - }, - selected = isSelected, - alwaysShowLabel = true, - onClick = { - if (!isSelected) { - selectedIndex.value = index - navController.navigate(screen.route) - } - } - ) - } - } -} \ No newline at end of file diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainContent.kt b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainContent.kt index fd19e217..14f2a144 100644 --- a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainContent.kt +++ b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -48,15 +48,11 @@ import com.kodeco.learn.ui.home.HomeContent import com.kodeco.learn.ui.latest.LatestContent import com.kodeco.learn.ui.search.SearchContent import kotlinx.coroutines.CoroutineScope -import moe.tlaster.precompose.navigation.NavHost -import moe.tlaster.precompose.navigation.Navigator - -private val DEFAULT_SCREEN = BottomNavigationScreens.Home @OptIn(ExperimentalMaterialApi::class) @Composable fun MainContent( - navController: Navigator, + destination: BottomNavigationScreens, coroutineScope: CoroutineScope, bottomSheetScaffoldState: BottomSheetScaffoldState, selected: MutableState, @@ -67,7 +63,7 @@ fun MainContent( Column { MainScreenNavigationConfigurations( - navController = navController, + destination = destination, coroutineScope = coroutineScope, bottomSheetScaffoldState = bottomSheetScaffoldState, selected = selected, @@ -81,7 +77,7 @@ fun MainContent( @OptIn(ExperimentalMaterialApi::class) @Composable private fun MainScreenNavigationConfigurations( - navController: Navigator, + destination: BottomNavigationScreens, coroutineScope: CoroutineScope, bottomSheetScaffoldState: BottomSheetScaffoldState, selected: MutableState, @@ -90,41 +86,38 @@ private fun MainScreenNavigationConfigurations( onOpenEntry: (String) -> Unit ) { - NavHost( - navigator = navController, - initialRoute = DEFAULT_SCREEN.route - ) { - scene(BottomNavigationScreens.Home.route) { + when(destination) { + BottomNavigationScreens.Home -> { HomeContent( - selected = selected, - items = feeds, - coroutineScope = coroutineScope, - bottomSheetScaffoldState = bottomSheetScaffoldState, - onOpenEntry = onOpenEntry + selected = selected, + items = feeds, + coroutineScope = coroutineScope, + bottomSheetScaffoldState = bottomSheetScaffoldState, + onOpenEntry = onOpenEntry ) } - scene(BottomNavigationScreens.Bookmark.route) { + BottomNavigationScreens.Bookmark -> { BookmarkContent( - selected = selected, - items = bookmarks, - coroutineScope = coroutineScope, - bottomSheetScaffoldState = bottomSheetScaffoldState, - onOpenEntry = onOpenEntry + selected = selected, + items = bookmarks, + coroutineScope = coroutineScope, + bottomSheetScaffoldState = bottomSheetScaffoldState, + onOpenEntry = onOpenEntry ) } - scene(BottomNavigationScreens.Latest.route) { + BottomNavigationScreens.Latest -> { LatestContent( - items = feeds, - onOpenEntry = onOpenEntry + items = feeds, + onOpenEntry = onOpenEntry ) } - scene(BottomNavigationScreens.Search.route) { + BottomNavigationScreens.Search -> { SearchContent( - selected = selected, - items = feeds, - coroutineScope = coroutineScope, - bottomSheetScaffoldState = bottomSheetScaffoldState, - onOpenEntry = onOpenEntry + selected = selected, + items = feeds, + coroutineScope = coroutineScope, + bottomSheetScaffoldState = bottomSheetScaffoldState, + onOpenEntry = onOpenEntry ) } } diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainScreen.kt b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainScreen.kt index 1fc49b25..7051161d 100644 --- a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainScreen.kt +++ b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainScreen.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -40,7 +40,8 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.BottomSheetScaffold import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.rememberBottomSheetScaffoldState -import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteScaffold import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.State @@ -54,8 +55,9 @@ import com.kodeco.learn.data.model.GravatarEntry import com.kodeco.learn.data.model.KodecoEntry import com.kodeco.learn.data.model.PLATFORM import com.kodeco.learn.ui.home.HomeSheetContent -import moe.tlaster.precompose.navigation.rememberNavigator +import org.jetbrains.compose.resources.stringResource +private val DEFAULT_SCREEN = BottomNavigationScreens.Home private lateinit var selected: MutableState @OptIn(ExperimentalMaterialApi::class) @@ -76,7 +78,9 @@ fun MainScreen( BottomNavigationScreens.Search ) - val navController = rememberNavigator() + val currentDestination = remember { + mutableStateOf(DEFAULT_SCREEN) + } val coroutineScope = rememberCoroutineScope() val bottomSheetScaffoldState = rememberBottomSheetScaffoldState() @@ -100,33 +104,42 @@ fun MainScreen( scaffoldState = bottomSheetScaffoldState, sheetPeekHeight = 0.dp ) { - Scaffold( - topBar = { + NavigationSuiteScaffold( + navigationSuiteItems = { + bottomNavigationItems.forEach { screen -> + item( + icon = { + screen.icon() + }, + label = { + Text( + text = stringResource(screen.title) + ) + }, + selected = screen == currentDestination.value, + onClick = { currentDestination.value = screen } + ) + } + }, + content = { + Column( + modifier = Modifier.padding(it) + ) { MainTopAppBar( - profile = profile + profile = profile ) - }, - bottomBar = { - MainBottomBar( - navController = navController, - items = bottomNavigationItems + + MainContent( + destination = currentDestination.value, + coroutineScope = coroutineScope, + bottomSheetScaffoldState = bottomSheetScaffoldState, + selected = selected, + feeds = feeds, + bookmarks = bookmarks, + onOpenEntry = onOpenEntry ) - }, - content = { - Column( - modifier = Modifier.padding(it) - ) { - MainContent( - navController = navController, - coroutineScope = coroutineScope, - bottomSheetScaffoldState = bottomSheetScaffoldState, - selected = selected, - feeds = feeds, - bookmarks = bookmarks, - onOpenEntry = onOpenEntry - ) - } } + } ) } } \ No newline at end of file diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainTopAppBar.kt b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainTopAppBar.kt index 605c5acd..97a009cd 100644 --- a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainTopAppBar.kt +++ b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainTopAppBar.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -49,17 +49,21 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.dp import com.kodeco.learn.components.AddImagePreview import com.kodeco.learn.data.model.GravatarEntry +import com.kodeco.learn.resources.Res +import com.kodeco.learn.resources.app_name +import com.kodeco.learn.resources.description_profile +import org.jetbrains.compose.resources.stringResource @OptIn(ExperimentalMaterial3Api::class) @Composable fun MainTopAppBar( - profile: GravatarEntry? + profile: GravatarEntry?, ) { CenterAlignedTopAppBar( title = { Text( - text = "learn" + text = stringResource(Res.string.app_name), ) }, actions = { @@ -69,15 +73,15 @@ fun MainTopAppBar( val avatarUrl = profile?.thumbnailUrl if (avatarUrl == null) { Icon( - imageVector = Icons.Filled.Person, - contentDescription = "User profile" + imageVector = Icons.Filled.Person, + contentDescription = stringResource(Res.string.description_profile) ) } else { AddImagePreview( - url = avatarUrl, - modifier = Modifier - .clip(CircleShape) - .size(25.dp) + url = avatarUrl, + modifier = Modifier + .clip(CircleShape) + .size(25.dp) ) } } diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/search/SearchContent.kt b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/search/SearchContent.kt index 4e2a4d00..b816f6b3 100644 --- a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/search/SearchContent.kt +++ b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/search/SearchContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -51,13 +51,15 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.snapshots.SnapshotStateMap import androidx.compose.ui.Modifier import androidx.compose.ui.focus.onFocusChanged -import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import com.kodeco.learn.data.model.KodecoEntry import com.kodeco.learn.data.model.PLATFORM import com.kodeco.learn.platform.Logger +import com.kodeco.learn.resources.Res +import com.kodeco.learn.resources.ic_search import com.kodeco.learn.ui.common.AddEntryContent import kotlinx.coroutines.CoroutineScope +import org.jetbrains.compose.resources.painterResource private const val TAG = "SearchContent" @@ -140,7 +142,7 @@ fun AddSearchField(search: MutableState) { ) }, leadingIcon = { - val resource = painterResource("images/ic_search.xml") + val resource = painterResource(Res.drawable.ic_search) val description = "Search for a specific article" Icon( diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Color.kt b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Color.kt index a594ad49..2e781c25 100644 --- a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Color.kt +++ b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Color.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Shape.kt b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Shape.kt index 8964a873..329ab7f5 100644 --- a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Shape.kt +++ b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Shape.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Theme.kt b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Theme.kt index 49e5b7eb..50c564f8 100644 --- a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Theme.kt +++ b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Theme.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -70,7 +70,7 @@ fun KodecoTheme( MaterialTheme( colorScheme = colorScheme, - typography = Typography, + typography = Typography(OpenSansFontFamily()), content = content ) } \ No newline at end of file diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Type.kt b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Type.kt index cd4e4933..48aa65b3 100644 --- a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Type.kt +++ b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Type.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -35,59 +35,102 @@ package com.kodeco.learn.ui.theme import androidx.compose.material3.Typography +import androidx.compose.runtime.Composable import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.platform.Font import androidx.compose.ui.unit.sp +import com.kodeco.learn.resources.Res +import com.kodeco.learn.resources.opensans_bold +import com.kodeco.learn.resources.opensans_extrabold +import com.kodeco.learn.resources.opensans_light +import com.kodeco.learn.resources.opensans_regular +import com.kodeco.learn.resources.opensans_semibold +import org.jetbrains.compose.resources.Font private val fontSizeBig = 16.sp private val fontSizeMedium = 15.sp private val fontSizeSmall = 14.sp private val fontSizeTiny = 12.sp -private val OpenSansFontFamily = FontFamily( - Font("font/opensans_bold.ttf", FontWeight.Bold), - Font("font/opensans_extrabold.ttf", FontWeight.ExtraBold), - Font("font/opensans_light.ttf", FontWeight.Light), - Font("font/opensans_regular.ttf", FontWeight.Normal), - Font("font/opensans_semibold.ttf", FontWeight.SemiBold), +@Composable +fun OpenSansFontFamily() = FontFamily( + Font(Res.font.opensans_bold, FontWeight.Bold, FontStyle.Normal), + Font(Res.font.opensans_extrabold, FontWeight.ExtraBold, FontStyle.Normal), + Font(Res.font.opensans_light, FontWeight.Light, FontStyle.Normal), + Font(Res.font.opensans_regular, FontWeight.Normal, FontStyle.Normal), + Font(Res.font.opensans_semibold, FontWeight.SemiBold, FontStyle.Normal) ) // Set of Material typography styles to start with -val Typography = Typography( +fun Typography(family: FontFamily) = Typography( headlineLarge = TextStyle( - fontFamily = OpenSansFontFamily, + fontFamily = family, fontWeight = FontWeight.Bold, fontSize = fontSizeMedium ), headlineMedium = TextStyle( - fontFamily = OpenSansFontFamily, + fontFamily = family, fontWeight = FontWeight.Normal, fontSize = fontSizeSmall ), headlineSmall = TextStyle( - fontFamily = OpenSansFontFamily, + fontFamily = family, fontWeight = FontWeight.Bold, fontSize = fontSizeTiny ), bodyLarge = TextStyle( - fontFamily = OpenSansFontFamily, + fontFamily = family, fontWeight = FontWeight.Normal, fontSize = fontSizeBig ), bodyMedium = TextStyle( - fontFamily = OpenSansFontFamily, + fontFamily = family, fontWeight = FontWeight.Bold, fontSize = fontSizeSmall ), bodySmall = TextStyle( - fontFamily = OpenSansFontFamily, + fontFamily = family, + fontSize = fontSizeSmall + ), + + titleLarge = TextStyle( + fontFamily = family, + fontWeight = FontWeight.Normal, + fontSize = fontSizeBig + ), + + titleMedium = TextStyle( + fontFamily = family, + fontWeight = FontWeight.Bold, + fontSize = fontSizeSmall + ), + + titleSmall = TextStyle( + fontFamily = family, + fontSize = fontSizeSmall + ), + + labelLarge = TextStyle( + fontFamily = family, + fontWeight = FontWeight.Normal, + fontSize = fontSizeBig + ), + + labelMedium = TextStyle( + fontFamily = family, + fontWeight = FontWeight.Bold, + fontSize = fontSizeSmall + ), + + labelSmall = TextStyle( + fontFamily = family, fontSize = fontSizeSmall ) ) \ No newline at end of file diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/utils/Utils.kt b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/utils/Utils.kt index a92d0ad1..6e58ae85 100644 --- a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/utils/Utils.kt +++ b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/utils/Utils.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -35,7 +35,7 @@ package com.kodeco.learn.utils import com.kodeco.learn.platform.Logger -import kotlinx.datetime.toInstant +import kotlinx.datetime.Instant import java.text.SimpleDateFormat import java.util.Date import java.util.Locale @@ -47,7 +47,7 @@ private val simpleDateFormat = SimpleDateFormat("yyyy/MM/dd", Locale.getDefault( fun converterIso8601ToReadableDate(date: String): String { return try { - val instant = date.toInstant() + val instant = Instant.parse(date) val millis = Date(instant.toEpochMilliseconds()) return simpleDateFormat.format(millis) } catch (e: Exception) { diff --git a/12-networking/projects/final/gradle.properties b/12-networking/projects/final/gradle.properties index 1677b55e..27359d2f 100644 --- a/12-networking/projects/final/gradle.properties +++ b/12-networking/projects/final/gradle.properties @@ -9,7 +9,6 @@ org.gradle.jvmargs=-Xmx6g -XX:+UseParallelGC # MPP kotlin.mpp.enableCInteropCommonization=true kotlin.mpp.stability.nowarn=true -kotlin.mpp.androidSourceSetLayoutVersion=2 # https://blog.jetbrains.com/kotlin/2022/07/a-new-approach-to-incremental-compilation-in-kotlin/ kotlin.incremental.useClasspathSnapshot=true diff --git a/12-networking/projects/final/gradle/libs.versions.toml b/12-networking/projects/final/gradle/libs.versions.toml index 877093de..5577f102 100644 --- a/12-networking/projects/final/gradle/libs.versions.toml +++ b/12-networking/projects/final/gradle/libs.versions.toml @@ -1,25 +1,23 @@ [versions] -gradle = "8.1.2" -android-sdk-compile = "34" +gradle = "8.8.0" +android-sdk-compile = "35" android-sdk-min = "24" -android-sdk-target = "34" -android-compose-compiler = "1.5.3" -android-material = "1.10.0" -androidx-compose-bom = "2023.10.00" -androidx-lifecycle-runtime-ktx = "2.6.2" -androidx-navigation-compose = "2.7.4" -coil = "2.4.0" -image-loader = "1.6.7" +android-sdk-target = "35" +android-material = "1.12.0" +androidx-compose-bom = "2025.01.01" +androidx-lifecycle-runtime-ktx = "2.8.7" +androidx-navigation-compose = "2.8.6" +coil = "2.7.0" +image-loader = "1.10.0" korio = "4.0.10" -kotlin = "1.9.10" -kotlinx-datetime = "0.4.1" -kotlinx-serialization-json = "1.6.0" -ktor = "2.3.4" -jetbrains-compose = "1.5.3" -junit = "4.13.2" -okio = "3.5.0" -precompose = "1.5.3" -sqldelight = "2.0.0" +kotlin = "2.1.0" +kotlinx-datetime = "0.6.1" +kotlinx-serialization-json = "1.7.3" +ktor = "3.0.3" +jetbrains-compose = "1.7.3" +jetbrains-compose-lifecycle = "2.8.0" +okio = "3.10.2" +sqldelight = "2.0.2" [libraries] android-material = { module = "com.google.android.material:material", version.ref = "android-material" } @@ -34,33 +32,33 @@ androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" } androidx-lifecycle-runtime-ktx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "androidx-lifecycle-runtime-ktx" } androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "androidx-navigation-compose" } +jetbrains-compose-lifecycle = { module = "org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "jetbrains-compose-lifecycle" } + cash-sqldelight-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" } cash-sqldelight-jvm = { module = "app.cash.sqldelight:sqlite-driver", version.ref = "sqldelight" } cash-sqldelight-native = { module = "app.cash.sqldelight:native-driver", version.ref = "sqldelight" } image-coil = { module = "io.coil-kt:coil-compose", version.ref = "coil" } image-loader = { module = "io.github.qdsfdhvh:image-loader", version.ref = "image-loader" } -junit = { module = "junit:junit", version.ref = "junit" } korio = { module = "com.soywiz.korlibs.korio:korio", version.ref = "korio" } kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinx-datetime" } kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization-json" } ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" } -ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" } ktor-client-serialization = { module = "io.ktor:ktor-client-serialization", version.ref = "ktor" } ktor-client-android = { module = "io.ktor:ktor-client-android", version.ref = "ktor" } ktor-client-ios = { module = "io.ktor:ktor-client-ios", version.ref = "ktor" } +ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" } +ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" } ktor-client-logging = { module = "io.ktor:ktor-client-logging", version.ref = "ktor" } ktor-client-mock = { module = "io.ktor:ktor-client-mock", version.ref = "ktor" } -ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" } okio = { module = "com.squareup.okio:okio", version.ref = "okio" } -precompose-viewmodel = { module = "moe.tlaster:precompose-viewmodel", version.ref = "precompose" } -precompose = { module = "moe.tlaster:precompose", version.ref = "precompose" } [plugins] android-application = { id = "com.android.application", version.ref = "gradle" } android-library = { id = "com.android.library", version.ref = "gradle" } cash-sqldelight = { id = "app.cash.sqldelight", version.ref = "sqldelight" } jetbrains-compose = { id = "org.jetbrains.compose", version.ref = "jetbrains-compose" } +jetbrains-compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } jetbrains-kotlin = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } jetbrains-kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } -jetbrains-kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" } jetbrains-kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } +jetbrains-kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" } \ No newline at end of file diff --git a/12-networking/projects/final/gradle/wrapper/gradle-wrapper.properties b/12-networking/projects/final/gradle/wrapper/gradle-wrapper.properties index 4b932409..5a450493 100644 --- a/12-networking/projects/final/gradle/wrapper/gradle-wrapper.properties +++ b/12-networking/projects/final/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Wed Jul 21 00:48:56 WEST 2021 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME diff --git a/12-networking/projects/final/iosApp/iosApp.xcodeproj/project.pbxproj b/12-networking/projects/final/iosApp/iosApp.xcodeproj/project.pbxproj index e524a599..f3346292 100644 --- a/12-networking/projects/final/iosApp/iosApp.xcodeproj/project.pbxproj +++ b/12-networking/projects/final/iosApp/iosApp.xcodeproj/project.pbxproj @@ -17,7 +17,7 @@ 670990692715023E0048A7B5 /* SearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 670990682715023E0048A7B5 /* SearchView.swift */; }; 6709909D2717ABF80048A7B5 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6709909C2717ABF80048A7B5 /* Utils.swift */; }; 6761C5672A9B4AD1008BB48B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6761C5662A9B4AD1008BB48B /* LaunchScreen.storyboard */; }; - 6763BD852AA6613400A70BAA /* MainToolbarContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6763BD842AA6613400A70BAA /* MainToolbarContent.swift */; }; + 6763BD882AA6B9CD00A70BAA /* MainToolbarContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6763BD872AA6B9CD00A70BAA /* MainToolbarContent.swift */; }; 67A1CBAB27ADFD27005629A1 /* Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67A1CBAA27ADFD27005629A1 /* Actions.swift */; }; 67BD5C082A9B555900FFDFEA /* SDWebImageSwiftUI in Frameworks */ = {isa = PBXBuildFile; productRef = 67BD5C072A9B555900FFDFEA /* SDWebImageSwiftUI */; }; 67C6FF262A98FC8D008A2221 /* KodecoEntryViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67C6FF252A98FC8D008A2221 /* KodecoEntryViewModel.swift */; }; @@ -41,8 +41,8 @@ 670990682715023E0048A7B5 /* SearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchView.swift; sourceTree = ""; }; 6709909C2717ABF80048A7B5 /* Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = ""; }; 6761C5662A9B4AD1008BB48B /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; - 6763BD832AA6402000A70BAA /* iosApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iosApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 6763BD842AA6613400A70BAA /* MainToolbarContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainToolbarContent.swift; sourceTree = ""; }; + 6763BD862AA6B93300A70BAA /* iosApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iosApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 6763BD872AA6B9CD00A70BAA /* MainToolbarContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainToolbarContent.swift; sourceTree = ""; }; 67A1CBAA27ADFD27005629A1 /* Actions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Actions.swift; sourceTree = ""; }; 67C6FF252A98FC8D008A2221 /* KodecoEntryViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KodecoEntryViewModel.swift; sourceTree = ""; }; 67C6FF292A98FD38008A2221 /* OpenSansBold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = OpenSansBold.ttf; sourceTree = ""; }; @@ -109,7 +109,7 @@ isa = PBXGroup; children = ( 7555FF7D242A565900829871 /* iosApp */, - 6763BD832AA6402000A70BAA /* iosApp.app */, + 6763BD862AA6B93300A70BAA /* iosApp.app */, ); sourceTree = ""; }; @@ -130,7 +130,7 @@ 670990682715023E0048A7B5 /* SearchView.swift */, 67C6FF252A98FC8D008A2221 /* KodecoEntryViewModel.swift */, 6761C5662A9B4AD1008BB48B /* LaunchScreen.storyboard */, - 6763BD842AA6613400A70BAA /* MainToolbarContent.swift */, + 6763BD872AA6B9CD00A70BAA /* MainToolbarContent.swift */, ); path = iosApp; sourceTree = ""; @@ -157,7 +157,7 @@ 67BD5C072A9B555900FFDFEA /* SDWebImageSwiftUI */, ); productName = iosApp; - productReference = 6763BD832AA6402000A70BAA /* iosApp.app */; + productReference = 6763BD862AA6B93300A70BAA /* iosApp.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ @@ -267,9 +267,9 @@ 67099063271501C00048A7B5 /* HomeView.swift in Sources */, 6709909D2717ABF80048A7B5 /* Utils.swift in Sources */, 67C6FF342A98FD95008A2221 /* KodecoEntryRow.swift in Sources */, + 6763BD882AA6B9CD00A70BAA /* MainToolbarContent.swift in Sources */, 7555FF83242A565900829871 /* ContentView.swift in Sources */, 67A1CBAB27ADFD27005629A1 /* Actions.swift in Sources */, - 6763BD852AA6613400A70BAA /* MainToolbarContent.swift in Sources */, 67C6FF262A98FC8D008A2221 /* KodecoEntryViewModel.swift in Sources */, 67099067271502210048A7B5 /* LatestView.swift in Sources */, ); diff --git a/12-networking/projects/final/iosApp/iosApp/BookmarkView.swift b/12-networking/projects/final/iosApp/iosApp/BookmarkView.swift index 41791b2c..2760077d 100644 --- a/12-networking/projects/final/iosApp/iosApp/BookmarkView.swift +++ b/12-networking/projects/final/iosApp/iosApp/BookmarkView.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal @@ -32,7 +32,6 @@ import SwiftUI import SharedKit -import SDWebImageSwiftUI struct BookmarkView: View { let TAG = "BookmarkView" diff --git a/12-networking/projects/final/iosApp/iosApp/ContentView.swift b/12-networking/projects/final/iosApp/iosApp/ContentView.swift index a067502c..233c88f6 100644 --- a/12-networking/projects/final/iosApp/iosApp/ContentView.swift +++ b/12-networking/projects/final/iosApp/iosApp/ContentView.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/iosApp/iosApp/HomeView.swift b/12-networking/projects/final/iosApp/iosApp/HomeView.swift index 43052702..4cb0245f 100644 --- a/12-networking/projects/final/iosApp/iosApp/HomeView.swift +++ b/12-networking/projects/final/iosApp/iosApp/HomeView.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/iosApp/iosApp/KodecoEntryViewModel.swift b/12-networking/projects/final/iosApp/iosApp/KodecoEntryViewModel.swift index 5239b41d..531e26e0 100644 --- a/12-networking/projects/final/iosApp/iosApp/KodecoEntryViewModel.swift +++ b/12-networking/projects/final/iosApp/iosApp/KodecoEntryViewModel.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/iosApp/iosApp/LatestView.swift b/12-networking/projects/final/iosApp/iosApp/LatestView.swift index 3b004330..e87ff438 100644 --- a/12-networking/projects/final/iosApp/iosApp/LatestView.swift +++ b/12-networking/projects/final/iosApp/iosApp/LatestView.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/iosApp/iosApp/MainToolbarContent.swift b/12-networking/projects/final/iosApp/iosApp/MainToolbarContent.swift index 51c10955..8fb616f5 100644 --- a/12-networking/projects/final/iosApp/iosApp/MainToolbarContent.swift +++ b/12-networking/projects/final/iosApp/iosApp/MainToolbarContent.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/iosApp/iosApp/SearchView.swift b/12-networking/projects/final/iosApp/iosApp/SearchView.swift index 2c4b4089..91be014e 100644 --- a/12-networking/projects/final/iosApp/iosApp/SearchView.swift +++ b/12-networking/projects/final/iosApp/iosApp/SearchView.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/iosApp/iosApp/common/KodecoEntryRow.swift b/12-networking/projects/final/iosApp/iosApp/common/KodecoEntryRow.swift index 600de5ba..087a489d 100644 --- a/12-networking/projects/final/iosApp/iosApp/common/KodecoEntryRow.swift +++ b/12-networking/projects/final/iosApp/iosApp/common/KodecoEntryRow.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal @@ -58,7 +58,6 @@ struct KodecoEntryRow: View { VStack(alignment: .leading) { HStack { if item.imageUrl.isEmpty { - Rectangle().foregroundColor(.gray) Image("kodeco") .resizable() .frame(width: 50, height: 50) diff --git a/12-networking/projects/final/iosApp/iosApp/extensions/BookmarkClient.swift b/12-networking/projects/final/iosApp/iosApp/extensions/BookmarkClient.swift index a962b101..6f2435ec 100644 --- a/12-networking/projects/final/iosApp/iosApp/extensions/BookmarkClient.swift +++ b/12-networking/projects/final/iosApp/iosApp/extensions/BookmarkClient.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/iosApp/iosApp/extensions/FeedClient.swift b/12-networking/projects/final/iosApp/iosApp/extensions/FeedClient.swift index 8bc0e718..dd07e43e 100644 --- a/12-networking/projects/final/iosApp/iosApp/extensions/FeedClient.swift +++ b/12-networking/projects/final/iosApp/iosApp/extensions/FeedClient.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/iosApp/iosApp/iOSApp.swift b/12-networking/projects/final/iosApp/iosApp/iOSApp.swift index ace71a32..868ad2fe 100644 --- a/12-networking/projects/final/iosApp/iosApp/iOSApp.swift +++ b/12-networking/projects/final/iosApp/iosApp/iOSApp.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/iosApp/iosApp/utils/Actions.swift b/12-networking/projects/final/iosApp/iosApp/utils/Actions.swift index 35253b96..1337bb35 100644 --- a/12-networking/projects/final/iosApp/iosApp/utils/Actions.swift +++ b/12-networking/projects/final/iosApp/iosApp/utils/Actions.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/iosApp/iosApp/utils/Utils.swift b/12-networking/projects/final/iosApp/iosApp/utils/Utils.swift index 4463f1f3..621ebcf4 100644 --- a/12-networking/projects/final/iosApp/iosApp/utils/Utils.swift +++ b/12-networking/projects/final/iosApp/iosApp/utils/Utils.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/settings.gradle.kts b/12-networking/projects/final/settings.gradle.kts index 56713c61..97b54fa6 100644 --- a/12-networking/projects/final/settings.gradle.kts +++ b/12-networking/projects/final/settings.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/shared-dto/build.gradle.kts b/12-networking/projects/final/shared-dto/build.gradle.kts index 3deed4a4..23ab3b4d 100644 --- a/12-networking/projects/final/shared-dto/build.gradle.kts +++ b/12-networking/projects/final/shared-dto/build.gradle.kts @@ -1,53 +1,69 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + plugins { - kotlin("multiplatform") - id("com.android.library") - alias(libs.plugins.jetbrains.kotlin.parcelize) - alias(libs.plugins.jetbrains.kotlin.serialization) + kotlin("multiplatform") + id("com.android.library") + + alias(libs.plugins.jetbrains.kotlin.parcelize) + alias(libs.plugins.jetbrains.kotlin.serialization) } -@OptIn(org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi::class) kotlin { - targetHierarchy.default() - androidTarget() + androidTarget { + compilerOptions { + // Issue #KT-58892: https://youtrack.jetbrains.com/issue/KT-58892/K2-Parcelize-doesnt-work-in-common-code-when-expect-annotation-is-actualized-with-typealias-to-Parcelize + freeCompilerArgs.addAll("-P", "plugin:org.jetbrains.kotlin.parcelize:additionalAnnotation=com.kodeco.learn.platform.Parcelize") + } + compilations.all { + compileTaskProvider.configure { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_17) + } + } + } + } - jvm() + jvm() - listOf( - iosX64(), - iosArm64(), - iosSimulatorArm64() - ).forEach { - it.binaries.framework { - baseName = "shared-dto" - } + listOf( + iosX64(), + iosArm64(), + iosSimulatorArm64() + ).forEach { + it.binaries.framework { + baseName = "shared-dto" } + } - sourceSets { - getByName("commonMain") { - dependencies { - implementation(libs.kotlinx.serialization.json) - } - } - getByName("commonTest") { - dependencies { - implementation(kotlin("test")) - } - } + sourceSets { + commonMain { + dependencies { + implementation(libs.kotlinx.serialization.json) + } } + } } android { - namespace = "com.kodeco.shared" + namespace = "com.kodeco.shared" - compileSdk = 33 + compileSdk = libs.versions.android.sdk.compile.get().toInt() - defaultConfig { - minSdk = 24 - } + defaultConfig { + minSdk = libs.versions.android.sdk.min.get().toInt() + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } +} - compileOptions { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 +kotlin.targets.configureEach { + compilations.configureEach { + compileTaskProvider.get().compilerOptions { + freeCompilerArgs.add("-Xexpect-actual-classes") } + } } \ No newline at end of file diff --git a/12-networking/projects/final/shared-dto/src/androidMain/kotlin/com/kodeco/learn/platform/Parcelable.android.kt b/12-networking/projects/final/shared-dto/src/androidMain/kotlin/com/kodeco/learn/platform/Parcelable.android.kt index 1fc85362..fefdce70 100644 --- a/12-networking/projects/final/shared-dto/src/androidMain/kotlin/com/kodeco/learn/platform/Parcelable.android.kt +++ b/12-networking/projects/final/shared-dto/src/androidMain/kotlin/com/kodeco/learn/platform/Parcelable.android.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -35,4 +35,4 @@ package com.kodeco.learn.platform actual typealias Parcelable = android.os.Parcelable -actual typealias Parcelize = kotlinx.android.parcel.Parcelize \ No newline at end of file +actual typealias Parcelize = kotlinx.parcelize.Parcelize \ No newline at end of file diff --git a/12-networking/projects/final/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/KodecoSerializer.kt b/12-networking/projects/final/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/KodecoSerializer.kt index e3bc23dd..3c73cd9f 100644 --- a/12-networking/projects/final/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/KodecoSerializer.kt +++ b/12-networking/projects/final/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/KodecoSerializer.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -62,5 +62,5 @@ object KodecoSerializer : KSerializer { } private fun findByKey(key: String, default: PLATFORM = PLATFORM.ALL): PLATFORM { - return PLATFORM.values().find { it.value.lowercase() == key.lowercase() } ?: default + return PLATFORM.entries.find { it.value.lowercase() == key.lowercase() } ?: default } \ No newline at end of file diff --git a/12-networking/projects/final/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/GravatarContent.kt b/12-networking/projects/final/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/GravatarContent.kt index 3f93c73d..09160a3b 100644 --- a/12-networking/projects/final/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/GravatarContent.kt +++ b/12-networking/projects/final/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/GravatarContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/KodecoContent.kt b/12-networking/projects/final/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/KodecoContent.kt index 7f88308d..272cbcc9 100644 --- a/12-networking/projects/final/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/KodecoContent.kt +++ b/12-networking/projects/final/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/KodecoContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/KodecoEntry.kt b/12-networking/projects/final/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/KodecoEntry.kt index bae3fe09..d028d2c8 100644 --- a/12-networking/projects/final/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/KodecoEntry.kt +++ b/12-networking/projects/final/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/KodecoEntry.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,8 +38,8 @@ import com.kodeco.learn.platform.Parcelable import com.kodeco.learn.platform.Parcelize import kotlinx.serialization.Serializable -@Serializable @Parcelize +@Serializable data class KodecoEntry( val id: String = "", val link: String = "", diff --git a/12-networking/projects/final/shared-dto/src/commonMain/kotlin/com/kodeco/learn/platform/Parcelable.common.kt b/12-networking/projects/final/shared-dto/src/commonMain/kotlin/com/kodeco/learn/platform/Parcelable.common.kt index eff22a1b..b2bc0d45 100644 --- a/12-networking/projects/final/shared-dto/src/commonMain/kotlin/com/kodeco/learn/platform/Parcelable.common.kt +++ b/12-networking/projects/final/shared-dto/src/commonMain/kotlin/com/kodeco/learn/platform/Parcelable.common.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/shared-dto/src/iosMain/kotlin/com/kodeco/learn/platform/Parcelable.ios.kt b/12-networking/projects/final/shared-dto/src/iosMain/kotlin/com/kodeco/learn/platform/Parcelable.ios.kt index 540759c2..86d99b50 100644 --- a/12-networking/projects/final/shared-dto/src/iosMain/kotlin/com/kodeco/learn/platform/Parcelable.ios.kt +++ b/12-networking/projects/final/shared-dto/src/iosMain/kotlin/com/kodeco/learn/platform/Parcelable.ios.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/shared-dto/src/jvmMain/kotlin/com/kodeco/learn/platform/Parcelable.desktop.kt b/12-networking/projects/final/shared-dto/src/jvmMain/kotlin/com/kodeco/learn/platform/Parcelable.jvm.kt similarity index 98% rename from 12-networking/projects/final/shared-dto/src/jvmMain/kotlin/com/kodeco/learn/platform/Parcelable.desktop.kt rename to 12-networking/projects/final/shared-dto/src/jvmMain/kotlin/com/kodeco/learn/platform/Parcelable.jvm.kt index 540759c2..86d99b50 100644 --- a/12-networking/projects/final/shared-dto/src/jvmMain/kotlin/com/kodeco/learn/platform/Parcelable.desktop.kt +++ b/12-networking/projects/final/shared-dto/src/jvmMain/kotlin/com/kodeco/learn/platform/Parcelable.jvm.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/shared/build.gradle.kts b/12-networking/projects/final/shared/build.gradle.kts index 0f43105d..9c5898e3 100644 --- a/12-networking/projects/final/shared/build.gradle.kts +++ b/12-networking/projects/final/shared/build.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,19 +32,18 @@ * THE SOFTWARE. */ -@file:Suppress("OPT_IN_USAGE") - +import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework plugins { alias(libs.plugins.android.library) alias(libs.plugins.jetbrains.kotlin.multiplatform) - alias(libs.plugins.jetbrains.kotlin.parcelize) alias(libs.plugins.jetbrains.kotlin.serialization) + alias(libs.plugins.jetbrains.kotlin.parcelize) alias(libs.plugins.cash.sqldelight) } -version = "2.0" +version = "3.0" sqldelight { databases { @@ -72,9 +71,21 @@ android { } kotlin { - androidTarget() + androidTarget { + compilerOptions { + // Issue #KT-58892: https://youtrack.jetbrains.com/issue/KT-58892/K2-Parcelize-doesnt-work-in-common-code-when-expect-annotation-is-actualized-with-typealias-to-Parcelize + freeCompilerArgs.addAll("-P", "plugin:org.jetbrains.kotlin.parcelize:additionalAnnotation=com.kodeco.learn.platform.Parcelize") + } + compilations.all { + compileTaskProvider.configure { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_17) + } + } + } + } - jvm("desktop") + jvm() val xcf = XCFramework("SharedKit") @@ -92,67 +103,57 @@ kotlin { } sourceSets { - targetHierarchy.default() + applyDefaultHierarchyTemplate() - getByName("commonMain") { - dependencies { - api(project(":shared-dto")) + commonMain.dependencies { + api(project(":shared-dto")) - implementation(libs.kotlinx.datetime) - implementation(libs.kotlinx.serialization.json) + implementation(libs.kotlinx.datetime) + implementation(libs.kotlinx.serialization.json) - implementation(libs.ktor.client.core) - implementation(libs.ktor.client.serialization) - implementation(libs.ktor.client.content.negotiation) - implementation(libs.ktor.client.logging) - implementation(libs.ktor.serialization.kotlinx.json) + implementation(libs.ktor.client.core) + implementation(libs.ktor.client.serialization) + implementation(libs.ktor.client.content.negotiation) + implementation(libs.ktor.serialization.kotlinx.json) + implementation(libs.ktor.client.logging) - implementation(libs.okio) - implementation(libs.korio) - } + implementation(libs.okio) + implementation(libs.korio) } - getByName("commonTest") { - dependencies { - implementation(kotlin("test-common")) - implementation(kotlin("test-annotations-common")) + commonTest.dependencies { + implementation(kotlin("test-common")) + implementation(kotlin("test-annotations-common")) - implementation(kotlin("test-junit")) - implementation(libs.junit) - implementation(libs.ktor.client.mock) - } + implementation(libs.ktor.client.mock) } - getByName("androidMain") { - dependencies { - implementation(libs.cash.sqldelight.android) + androidMain.dependencies { + implementation(libs.cash.sqldelight.android) - implementation(libs.ktor.client.android) - } + implementation(libs.ktor.client.android) } - getByName("androidUnitTest") { - dependencies { - implementation(kotlin("test-junit")) - } + androidUnitTest.dependencies { + implementation(kotlin("test-junit")) } - getByName("desktopMain") { - dependencies { - implementation(libs.cash.sqldelight.jvm) - } + jvmMain.dependencies { + implementation(libs.cash.sqldelight.jvm) } - getByName("iosMain") { - dependencies { - implementation(libs.cash.sqldelight.native) + iosMain.dependencies { + implementation(libs.cash.sqldelight.native) - implementation(libs.ktor.client.ios) - } + implementation(libs.ktor.client.ios) } } } -kotlin.sourceSets.all { - languageSettings.optIn("kotlin.RequiresOptIn") +kotlin.targets.configureEach { + compilations.configureEach { + compileTaskProvider.get().compilerOptions { + freeCompilerArgs.add("-Xexpect-actual-classes") + } + } } \ No newline at end of file diff --git a/12-networking/projects/final/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Database.android.kt b/12-networking/projects/final/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Database.android.kt index 9872f353..43fab8bb 100644 --- a/12-networking/projects/final/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Database.android.kt +++ b/12-networking/projects/final/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Database.android.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Logger.android.kt b/12-networking/projects/final/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Logger.android.kt index 5ffe7c44..e69c17d0 100644 --- a/12-networking/projects/final/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Logger.android.kt +++ b/12-networking/projects/final/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Logger.android.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Test.android.kt b/12-networking/projects/final/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Test.android.kt index 0d643309..39447147 100644 --- a/12-networking/projects/final/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Test.android.kt +++ b/12-networking/projects/final/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Test.android.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/ServiceLocator.kt b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/ServiceLocator.kt index c1ebeb21..d36d288b 100644 --- a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/ServiceLocator.kt +++ b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/ServiceLocator.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/Values.kt b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/Values.kt index e12665e4..b5a9de54 100644 --- a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/Values.kt +++ b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/Values.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/data/FeedAPI.kt b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/data/FeedAPI.kt index 767acce9..5a78ff58 100644 --- a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/data/FeedAPI.kt +++ b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/data/FeedAPI.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/data/HttpClientLogger.kt b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/data/HttpClientLogger.kt index 24f7ddc0..31ae32a9 100644 --- a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/data/HttpClientLogger.kt +++ b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/data/HttpClientLogger.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/domain/GetFeedData.kt b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/domain/GetFeedData.kt index fbd6f56e..9e2b325d 100644 --- a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/domain/GetFeedData.kt +++ b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/domain/GetFeedData.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/domain/cb/BookmarkData.kt b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/domain/cb/BookmarkData.kt index 41f3cee7..325cfde4 100644 --- a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/domain/cb/BookmarkData.kt +++ b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/domain/cb/BookmarkData.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/domain/cb/FeedData.kt b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/domain/cb/FeedData.kt index f8840287..02fc36dd 100644 --- a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/domain/cb/FeedData.kt +++ b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/domain/cb/FeedData.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/domain/dao/KodecoEntryDAO.kt b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/domain/dao/KodecoEntryDAO.kt index 00e083cb..4237edb2 100644 --- a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/domain/dao/KodecoEntryDAO.kt +++ b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/domain/dao/KodecoEntryDAO.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Database.common.kt b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Database.common.kt index 2900ec9d..d6561751 100644 --- a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Database.common.kt +++ b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Database.common.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Logger.common.kt b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Logger.common.kt index a2fd9169..0315307a 100644 --- a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Logger.common.kt +++ b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Logger.common.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Test.common.kt b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Test.common.kt index a3df1ada..37fa556c 100644 --- a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Test.common.kt +++ b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Test.common.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/BookmarkPresenter.kt b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/BookmarkPresenter.kt index d57fa5e9..cdfec5a3 100644 --- a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/BookmarkPresenter.kt +++ b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/BookmarkPresenter.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/FeedPresenter.kt b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/FeedPresenter.kt index 5f4e9180..6e9ded11 100644 --- a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/FeedPresenter.kt +++ b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/FeedPresenter.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -36,6 +36,7 @@ package com.kodeco.learn.presentation import com.kodeco.learn.data.model.GravatarEntry import com.kodeco.learn.data.model.KodecoContent +import com.kodeco.learn.data.model.KodecoEntry import com.kodeco.learn.data.model.PLATFORM import com.kodeco.learn.domain.GetFeedData import com.kodeco.learn.domain.cb.FeedData @@ -58,6 +59,50 @@ private const val KODECO_CONTENT = "[" + "{\"platform\":\"growth\", \"url\":\"https://kodeco.com/professional-growth/feed\", \"image\":\"https://files.carolus.kodeco.com/gl22boss4ptciv7px3nnzcnct4ht?response_content_disposition=inline%3B+filename%3D%22progro.png%22%3B+filename%2A%3DUTF-8%27%27progro.png\"}" + "]" +private const val KODECO_ALL_FEED = """ + [ + { + "id": "https://www.kodeco.com/26244793-building-a-camera-app-with-swiftui-and-combine", + "link": "https://www.kodeco.com/26244793-building-a-camera-app-with-swiftui-and-combine", + "title": "Building a Camera App With SwiftUI and Combine [FREE]", + "summary":"Learn to natively build your own SwiftUI camera app using Combine and create fun filters using the power of Core Image.", + "updated": "2021-11-10T13:59:59Z" + }, + + { + "id": "https://www.kodeco.com/29045204-announcing-swiftui-by-tutorials-fourth-edition", + "link": "https://www.kodeco.com/29045204-announcing-swiftui-by-tutorials-fourth-edition", + "title": "Announcing SwiftUI by Tutorials, Fourth Edition! [FREE]", + "summary":"Build apps more efficiently with SwiftUI’s declarative approach and leave the old ways of imperative coding in the dust, with this freshly-updated book.", + "updated": "2021-11-10T13:44:43Z" + }, + + { + "id": "https://www.kodeco.com/books/swiftui-by-tutorialse", + "link": "https://www.kodeco.com/books/swiftui-by-tutorials", + "title": "SwiftUI by Tutorials [SUBSCRIBER]", + "summary":"Build fluid and engaging declarative UI for your apps — using less code — with SwiftUI!

SwiftUI by Tutorials is designed to help you learn how to transition from the “old way” of building your app UI with UIKit, to the “new way” of building responsive UI with modern declarative syntax with SwiftUI. This book is for readers who are comfortable building Swift apps, and want to make the exciting leap into building their app UI with modern, declarative code.

What is SwiftUI?

SwiftUI lets you build better apps, faster, and with less code. It’s a developer’s dream come true! With SwiftUI, you can design your user interfaces in a declarative way; instead of developing app interfaces in an imperative way, by coding all of the application state logic before time, you can instead define what your app’s UI should do in a particular state and let the underlying OS figure out how to do it. What’s more is that SwiftUI lets you build modern, responsive UI and animations for all Apple devices — not just iOS. So whether you’re building apps for iOS, watchOS, tvOS or any other Apple platform, you can use the same concise, natural language to describe your UI and have it look stunning — no matter where your code runs. In addition, SwiftUI’s built-in automatic support for things such as dark mode, localization and accessibility, along with Xcode 11 support for drag-and-drop design and instant preview makes it easier to build apps than ever before.

How is this book different than SwiftUI Apprentice?

Our other book on getting started with SwiftUI, SwiftUI Apprentice, is designed to teach new developers how to build iOS apps, using a SwiftUI-first approach. The goal of that book is to teach you fundamental development practices as you build out some fully-functional and great-looking apps! This book, SwiftUI by Tutorials, is designed for developers who have a solid background in iOS development, and are looking to make the leap from building apps with UIKit, to building apps with SwiftUI.", + "updated": "2021-11-10T00:00:00Z" + }, + + { + "id": "https://www.kodeco.com/26933987-flutter-ui-widgets", + "link": "https://www.kodeco.com/26933987-flutter-ui-widgets", + "title": "Flutter UI Widgets [SUBSCRIBER]", + "summary":"Explore commonly used UI widgets in Flutter and see how they relate to their native iOS and Android counterparts.", + "updated": "2021-11-09T00:00:00Z" + }, + + { + "id": "https://www.kodeco.com/26236685-shazamkit-tutorial-for-ios-getting-started", + "link": "https://www.kodeco.com/26236685-shazamkit-tutorial-for-ios-getting-started", + "title": "ShazamKit Tutorial for iOS: Getting Started [FREE]", + "summary":"Learn how to use ShazamKit to find information about specific audio recordings by matching a segment of that audio against a reference catalog of audio signatures.", + "updated": "2021-11-08T13:59:30Z" + } +] +""" + private const val GRAVATAR_EMAIL = "YOUR_GRAVATAR_EMAIL" class FeedPresenter(private val feed: GetFeedData) { @@ -68,6 +113,10 @@ class FeedPresenter(private val feed: GetFeedData) { json.decodeFromString(KODECO_CONTENT) } + val allFeeds: List by lazy { + json.decodeFromString(KODECO_ALL_FEED) + } + public fun fetchAllFeeds(cb: FeedData) { Logger.d(TAG, "fetchAllFeeds") @@ -93,7 +142,6 @@ class FeedPresenter(private val feed: GetFeedData) { } } - public fun fetchMyGravatar(cb: FeedData) { Logger.d(TAG, "fetchMyGravatar") diff --git a/12-networking/projects/final/shared/src/commonTest/kotlin/NetworkTests.kt b/12-networking/projects/final/shared/src/commonTest/kotlin/NetworkTests.kt index e15ff091..6564547b 100644 --- a/12-networking/projects/final/shared/src/commonTest/kotlin/NetworkTests.kt +++ b/12-networking/projects/final/shared/src/commonTest/kotlin/NetworkTests.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -47,8 +47,8 @@ import io.ktor.http.ContentType import io.ktor.http.HttpHeaders import io.ktor.http.headersOf import io.ktor.serialization.kotlinx.json.json -import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json +import kotlinx.serialization.encodeToString import kotlin.test.Test import kotlin.test.assertEquals diff --git a/12-networking/projects/final/shared/src/commonTest/kotlin/SerializationTests.kt b/12-networking/projects/final/shared/src/commonTest/kotlin/SerializationTests.kt index 5a2cfe8f..149a3135 100644 --- a/12-networking/projects/final/shared/src/commonTest/kotlin/SerializationTests.kt +++ b/12-networking/projects/final/shared/src/commonTest/kotlin/SerializationTests.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Database.ios.kt b/12-networking/projects/final/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Database.ios.kt index 1328413f..073d4cfd 100644 --- a/12-networking/projects/final/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Database.ios.kt +++ b/12-networking/projects/final/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Database.ios.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Logger.ios.kt b/12-networking/projects/final/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Logger.ios.kt index b8cb9781..4a0e1627 100644 --- a/12-networking/projects/final/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Logger.ios.kt +++ b/12-networking/projects/final/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Logger.ios.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Test.ios.kt b/12-networking/projects/final/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Test.ios.kt index 0d643309..39447147 100644 --- a/12-networking/projects/final/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Test.ios.kt +++ b/12-networking/projects/final/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Test.ios.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Database.desktop.kt b/12-networking/projects/final/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Database.jvm.kt similarity index 98% rename from 12-networking/projects/final/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Database.desktop.kt rename to 12-networking/projects/final/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Database.jvm.kt index 2e55f0e1..83304e3a 100644 --- a/12-networking/projects/final/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Database.desktop.kt +++ b/12-networking/projects/final/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Database.jvm.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Logger.desktop.kt b/12-networking/projects/final/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Logger.jvm.kt similarity index 98% rename from 12-networking/projects/final/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Logger.desktop.kt rename to 12-networking/projects/final/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Logger.jvm.kt index e77f3495..e68ad692 100644 --- a/12-networking/projects/final/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Logger.desktop.kt +++ b/12-networking/projects/final/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Logger.jvm.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/final/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Test.desktop.kt b/12-networking/projects/final/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Test.jvm.kt similarity index 98% rename from 12-networking/projects/final/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Test.desktop.kt rename to 12-networking/projects/final/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Test.jvm.kt index 0d643309..39447147 100644 --- a/12-networking/projects/final/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Test.desktop.kt +++ b/12-networking/projects/final/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Test.jvm.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal From a2c458558c5870662ebfd80f3a69406c5c373329 Mon Sep 17 00:00:00 2001 From: Carlos Mota Date: Mon, 3 Feb 2025 00:27:41 +0000 Subject: [PATCH 3/6] Ignore platform name case --- .../commonMain/kotlin/com/kodeco/learn/data/KodecoSerializer.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/12-networking/projects/starter/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/KodecoSerializer.kt b/12-networking/projects/starter/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/KodecoSerializer.kt index e6f73d77..3c73cd9f 100644 --- a/12-networking/projects/starter/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/KodecoSerializer.kt +++ b/12-networking/projects/starter/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/KodecoSerializer.kt @@ -62,5 +62,5 @@ object KodecoSerializer : KSerializer { } private fun findByKey(key: String, default: PLATFORM = PLATFORM.ALL): PLATFORM { - return PLATFORM.entries.find { it.value == key } ?: default + return PLATFORM.entries.find { it.value.lowercase() == key.lowercase() } ?: default } \ No newline at end of file From faa0c072c29dab5dc41c9508dce07a516382d412 Mon Sep 17 00:00:00 2001 From: Carlos Mota Date: Mon, 3 Feb 2025 00:37:25 +0000 Subject: [PATCH 4/6] Updated challenge project --- 12-networking/projects/challenge/.gitignore | 3 +- .../challenge/androidApp/build.gradle.kts | 12 +- .../com/kodeco/learn/KodecoApplication.kt | 2 +- .../kodeco/learn/components/ImagePreview.kt | 2 +- .../java/com/kodeco/learn/ui/MainActivity.kt | 2 +- .../learn/ui/bookmark/BookmarkContent.kt | 10 +- .../learn/ui/bookmark/BookmarkViewModel.kt | 2 +- .../kodeco/learn/ui/common/EmptyContent.kt | 2 +- .../kodeco/learn/ui/common/EntryContent.kt | 12 +- .../com/kodeco/learn/ui/home/FeedViewModel.kt | 2 +- .../com/kodeco/learn/ui/home/HomeContent.kt | 8 +- .../kodeco/learn/ui/home/HomeSheetContent.kt | 12 +- .../kodeco/learn/ui/latest/LatestContent.kt | 2 +- .../learn/ui/main/BottomNavigationScreens.kt | 2 +- .../com/kodeco/learn/ui/main/MainBottomBar.kt | 2 +- .../com/kodeco/learn/ui/main/MainContent.kt | 10 +- .../com/kodeco/learn/ui/main/MainScreen.kt | 10 +- .../com/kodeco/learn/ui/main/MainTopAppBar.kt | 14 +-- .../kodeco/learn/ui/search/SearchContent.kt | 8 +- .../java/com/kodeco/learn/ui/theme/Color.kt | 2 +- .../java/com/kodeco/learn/ui/theme/Shape.kt | 2 +- .../java/com/kodeco/learn/ui/theme/Theme.kt | 47 ++++---- .../java/com/kodeco/learn/ui/theme/Type.kt | 36 +++++- .../main/java/com/kodeco/learn/utils/Utils.kt | 6 +- .../projects/challenge/build.gradle.kts | 7 +- .../challenge/desktopApp/build.gradle.kts | 50 +++++--- .../drawable}/ic_bookmarks.xml | 0 .../composeResources/drawable}/ic_brand.xml | 0 .../composeResources/drawable}/ic_home.xml | 0 .../composeResources/drawable}/ic_latest.xml | 0 .../composeResources/drawable}/ic_more.xml | 0 .../composeResources/drawable}/ic_search.xml | 0 .../composeResources}/font/opensans_bold.ttf | Bin .../font/opensans_extrabold.ttf | Bin .../composeResources}/font/opensans_light.ttf | Bin .../font/opensans_regular.ttf | Bin .../font/opensans_semibold.ttf | Bin .../composeResources/values/strings.xml | 36 ++++++ .../jvmMain/kotlin/com/kodeco/learn/Main.kt | 13 ++- .../kodeco/learn/components/ImagePreview.kt | 18 +-- .../learn/ui/bookmark/BookmarkContent.kt | 2 +- .../learn/ui/bookmark/BookmarkViewModel.kt | 6 +- .../kodeco/learn/ui/common/EmptyContent.kt | 2 +- .../kodeco/learn/ui/common/EntryContent.kt | 19 ++-- .../com/kodeco/learn/ui/home/FeedViewModel.kt | 6 +- .../com/kodeco/learn/ui/home/HomeContent.kt | 2 +- .../kodeco/learn/ui/home/HomeSheetContent.kt | 13 ++- .../kodeco/learn/ui/latest/LatestContent.kt | 2 +- .../learn/ui/main/BottomNavigationScreens.kt | 41 ++++--- .../com/kodeco/learn/ui/main/MainBottomBar.kt | 107 ------------------ .../com/kodeco/learn/ui/main/MainContent.kt | 59 +++++----- .../com/kodeco/learn/ui/main/MainScreen.kt | 67 ++++++----- .../com/kodeco/learn/ui/main/MainTopAppBar.kt | 22 ++-- .../kodeco/learn/ui/search/SearchContent.kt | 8 +- .../kotlin/com/kodeco/learn/ui/theme/Color.kt | 2 +- .../kotlin/com/kodeco/learn/ui/theme/Shape.kt | 2 +- .../kotlin/com/kodeco/learn/ui/theme/Theme.kt | 4 +- .../kotlin/com/kodeco/learn/ui/theme/Type.kt | 73 +++++++++--- .../kotlin/com/kodeco/learn/utils/Utils.kt | 6 +- .../projects/challenge/gradle.properties | 1 - .../challenge/gradle/libs.versions.toml | 48 ++++---- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../iosApp/iosApp.xcodeproj/project.pbxproj | 14 +-- .../iosApp/iosApp/BookmarkView.swift | 3 +- .../challenge/iosApp/iosApp/ContentView.swift | 2 +- .../challenge/iosApp/iosApp/HomeView.swift | 2 +- .../iosApp/iosApp/KodecoEntryViewModel.swift | 2 +- .../challenge/iosApp/iosApp/LatestView.swift | 2 +- .../iosApp/iosApp/MainToolbarContent.swift | 2 +- .../challenge/iosApp/iosApp/SearchView.swift | 2 +- .../iosApp/iosApp/common/KodecoEntryRow.swift | 3 +- .../iosApp/extensions/BookmarkClient.swift | 2 +- .../iosApp/iosApp/extensions/FeedClient.swift | 2 +- .../challenge/iosApp/iosApp/iOSApp.swift | 2 +- .../iosApp/iosApp/utils/Actions.swift | 2 +- .../challenge/iosApp/iosApp/utils/Utils.swift | 2 +- .../projects/challenge/settings.gradle.kts | 2 +- .../challenge/shared-dto/build.gradle.kts | 86 ++++++++------ .../learn/platform/Parcelable.android.kt | 4 +- .../com/kodeco/learn/data/KodecoSerializer.kt | 4 +- .../learn/data/model/GravatarContent.kt | 2 +- .../kodeco/learn/data/model/KodecoContent.kt | 2 +- .../kodeco/learn/data/model/KodecoEntry.kt | 4 +- .../learn/platform/Parcelable.common.kt | 2 +- .../kodeco/learn/platform/Parcelable.ios.kt | 2 +- ...arcelable.desktop.kt => Parcelable.jvm.kt} | 2 +- .../challenge/shared/build.gradle.kts | 99 ++++++++-------- .../kodeco/learn/platform/Database.android.kt | 2 +- .../learn/platform/Identifier.android.kt | 2 +- .../kodeco/learn/platform/Logger.android.kt | 2 +- .../com/kodeco/learn/platform/Test.android.kt | 2 +- .../kotlin/com/kodeco/learn/ServiceLocator.kt | 2 +- .../kotlin/com/kodeco/learn/Values.kt | 2 +- .../kotlin/com/kodeco/learn/data/FeedAPI.kt | 2 +- .../com/kodeco/learn/data/HttpClientLogger.kt | 2 +- .../com/kodeco/learn/domain/GetFeedData.kt | 2 +- .../kodeco/learn/domain/cb/BookmarkData.kt | 2 +- .../com/kodeco/learn/domain/cb/FeedData.kt | 2 +- .../kodeco/learn/domain/dao/KodecoEntryDAO.kt | 2 +- .../kodeco/learn/platform/Database.common.kt | 2 +- .../learn/platform/Identifier.common.kt | 2 +- .../kodeco/learn/platform/Logger.common.kt | 2 +- .../com/kodeco/learn/platform/Test.common.kt | 2 +- .../learn/presentation/BookmarkPresenter.kt | 2 +- .../learn/presentation/FeedPresenter.kt | 52 ++++++++- .../src/commonTest/kotlin/NetworkTests.kt | 4 +- .../commonTest/kotlin/SerializationTests.kt | 2 +- .../com/kodeco/learn/platform/Database.ios.kt | 2 +- .../kodeco/learn/platform/Identifier.ios.kt | 2 +- .../com/kodeco/learn/platform/Logger.ios.kt | 2 +- .../com/kodeco/learn/platform/Test.ios.kt | 2 +- .../kodeco/learn/platform/Database.jvm.kt} | 2 +- .../kodeco/learn/platform/Identifier.jvm.kt} | 2 +- .../com/kodeco/learn/platform/Logger.jvm.kt} | 2 +- .../com/kodeco/learn/platform/Test.jvm.kt} | 2 +- 115 files changed, 657 insertions(+), 530 deletions(-) rename 12-networking/projects/challenge/desktopApp/src/{jvmMain/resources/images => commonMain/composeResources/drawable}/ic_bookmarks.xml (100%) rename 12-networking/projects/challenge/desktopApp/src/{jvmMain/resources/images => commonMain/composeResources/drawable}/ic_brand.xml (100%) rename 12-networking/projects/challenge/desktopApp/src/{jvmMain/resources/images => commonMain/composeResources/drawable}/ic_home.xml (100%) rename 12-networking/projects/challenge/desktopApp/src/{jvmMain/resources/images => commonMain/composeResources/drawable}/ic_latest.xml (100%) rename 12-networking/projects/challenge/desktopApp/src/{jvmMain/resources/images => commonMain/composeResources/drawable}/ic_more.xml (100%) rename 12-networking/projects/challenge/desktopApp/src/{jvmMain/resources/images => commonMain/composeResources/drawable}/ic_search.xml (100%) rename 12-networking/projects/challenge/desktopApp/src/{jvmMain/resources => commonMain/composeResources}/font/opensans_bold.ttf (100%) rename 12-networking/projects/challenge/desktopApp/src/{jvmMain/resources => commonMain/composeResources}/font/opensans_extrabold.ttf (100%) rename 12-networking/projects/challenge/desktopApp/src/{jvmMain/resources => commonMain/composeResources}/font/opensans_light.ttf (100%) rename 12-networking/projects/challenge/desktopApp/src/{jvmMain/resources => commonMain/composeResources}/font/opensans_regular.ttf (100%) rename 12-networking/projects/challenge/desktopApp/src/{jvmMain/resources => commonMain/composeResources}/font/opensans_semibold.ttf (100%) create mode 100644 12-networking/projects/challenge/desktopApp/src/commonMain/composeResources/values/strings.xml delete mode 100644 12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainBottomBar.kt rename 12-networking/projects/challenge/shared-dto/src/jvmMain/kotlin/com/kodeco/learn/platform/{Parcelable.desktop.kt => Parcelable.jvm.kt} (98%) rename 12-networking/projects/challenge/shared/src/{desktopMain/kotlin/com/kodeco/learn/platform/Database.desktop.kt => jvmMain/kotlin/com/kodeco/learn/platform/Database.jvm.kt} (98%) rename 12-networking/projects/challenge/shared/src/{desktopMain/kotlin/com/kodeco/learn/platform/Identifier.desktop.kt => jvmMain/kotlin/com/kodeco/learn/platform/Identifier.jvm.kt} (98%) rename 12-networking/projects/challenge/shared/src/{desktopMain/kotlin/com/kodeco/learn/platform/Logger.desktop.kt => jvmMain/kotlin/com/kodeco/learn/platform/Logger.jvm.kt} (98%) rename 12-networking/projects/challenge/shared/src/{desktopMain/kotlin/com/kodeco/learn/platform/Test.desktop.kt => jvmMain/kotlin/com/kodeco/learn/platform/Test.jvm.kt} (98%) diff --git a/12-networking/projects/challenge/.gitignore b/12-networking/projects/challenge/.gitignore index b1bb87f1..90d16852 100644 --- a/12-networking/projects/challenge/.gitignore +++ b/12-networking/projects/challenge/.gitignore @@ -15,8 +15,9 @@ bin/ gen/ out/ -# Gradle files +# Project files .gradle/ +.kotlin/ build/ androidApp/build desktopApp/build diff --git a/12-networking/projects/challenge/androidApp/build.gradle.kts b/12-networking/projects/challenge/androidApp/build.gradle.kts index 820caca5..9b6d2be3 100644 --- a/12-networking/projects/challenge/androidApp/build.gradle.kts +++ b/12-networking/projects/challenge/androidApp/build.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -35,6 +35,8 @@ plugins { id("com.android.application") kotlin("android") + + alias(libs.plugins.jetbrains.compose.compiler) } dependencies { @@ -63,8 +65,8 @@ android { applicationId = "com.kodeco.learn" minSdk = libs.versions.android.sdk.min.get().toInt() targetSdk = libs.versions.android.sdk.target.get().toInt() - versionCode = 2 - versionName = "2.0" + versionCode = 3 + versionName = "3.0" } buildTypes { @@ -86,10 +88,6 @@ android { jvmTarget = "17" } - composeOptions { - kotlinCompilerExtensionVersion = libs.versions.android.compose.compiler.get() - } - packaging { resources { excludes += "/META-INF/{AL2.0,LGPL2.1}" diff --git a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/KodecoApplication.kt b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/KodecoApplication.kt index 1dbfd1c6..bb5174e2 100644 --- a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/KodecoApplication.kt +++ b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/KodecoApplication.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/components/ImagePreview.kt b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/components/ImagePreview.kt index 9a33e6c5..b404d47e 100644 --- a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/components/ImagePreview.kt +++ b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/components/ImagePreview.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/MainActivity.kt b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/MainActivity.kt index 4d31c99a..7d616ec5 100644 --- a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/MainActivity.kt +++ b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/MainActivity.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/bookmark/BookmarkContent.kt b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/bookmark/BookmarkContent.kt index fb81f218..205fd1f1 100644 --- a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/bookmark/BookmarkContent.kt +++ b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/bookmark/BookmarkContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -37,8 +37,8 @@ package com.kodeco.learn.ui.bookmark import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.material.BottomSheetScaffoldState -import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.State @@ -53,7 +53,7 @@ import kotlinx.coroutines.CoroutineScope private const val TAG = "BookmarkContent" -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun BookmarkContent( selected: MutableState, @@ -80,7 +80,7 @@ fun BookmarkContent( } } -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun AddBookmarks( selected: MutableState, diff --git a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/bookmark/BookmarkViewModel.kt b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/bookmark/BookmarkViewModel.kt index b1b885a7..75b939f8 100644 --- a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/bookmark/BookmarkViewModel.kt +++ b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/bookmark/BookmarkViewModel.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/common/EmptyContent.kt b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/common/EmptyContent.kt index bd221c2d..ba7b331f 100644 --- a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/common/EmptyContent.kt +++ b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/common/EmptyContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/common/EntryContent.kt b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/common/EntryContent.kt index 28ea5f76..5107a643 100644 --- a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/common/EntryContent.kt +++ b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/common/EntryContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -45,9 +45,9 @@ 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.BottomSheetScaffoldState -import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material3.Divider +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -69,7 +69,7 @@ import kotlinx.coroutines.launch private const val TAG = "EntryContent" -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun AddEntryContent( item: KodecoEntry, @@ -169,7 +169,7 @@ fun AddEntryContent( Spacer(modifier = Modifier.height(16.dp)) if (divider) { - Divider( + HorizontalDivider( modifier = Modifier.fillMaxWidth(), thickness = 1.dp ) diff --git a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/home/FeedViewModel.kt b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/home/FeedViewModel.kt index 4b527ad3..ec3a5534 100644 --- a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/home/FeedViewModel.kt +++ b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/home/FeedViewModel.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/home/HomeContent.kt b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/home/HomeContent.kt index 99dd0f0d..a1a30553 100644 --- a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/home/HomeContent.kt +++ b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/home/HomeContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -47,8 +47,8 @@ import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.BottomSheetScaffoldState -import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState @@ -69,7 +69,7 @@ import kotlinx.coroutines.CoroutineScope private const val TAG = "HomeContent" -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun HomeContent( selected: MutableState, diff --git a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/home/HomeSheetContent.kt b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/home/HomeSheetContent.kt index 88890b61..d4d1a53a 100644 --- a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/home/HomeSheetContent.kt +++ b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/home/HomeSheetContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -39,8 +39,8 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.material.BottomSheetScaffoldState -import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState @@ -55,7 +55,7 @@ import kotlinx.coroutines.launch private const val TAG = "HomeSheetContent" -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun HomeSheetContent( item: MutableState, @@ -76,7 +76,7 @@ fun HomeSheetContent( .fillMaxWidth() .clickable { coroutineScope.launch { - bottomSheetScaffoldState.bottomSheetState.collapse() + bottomSheetScaffoldState.bottomSheetState.hide() } onUpdateBookmark(item.value) @@ -102,7 +102,7 @@ fun HomeSheetContent( .fillMaxWidth() .clickable { coroutineScope.launch { - bottomSheetScaffoldState.bottomSheetState.collapse() + bottomSheetScaffoldState.bottomSheetState.hide() } onShareAsLink(item.value) diff --git a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/latest/LatestContent.kt b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/latest/LatestContent.kt index 32045322..382e52a5 100644 --- a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/latest/LatestContent.kt +++ b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/latest/LatestContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/main/BottomNavigationScreens.kt b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/main/BottomNavigationScreens.kt index 8e3f6ebf..1e97ea99 100644 --- a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/main/BottomNavigationScreens.kt +++ b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/main/BottomNavigationScreens.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/main/MainBottomBar.kt b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/main/MainBottomBar.kt index 94a16670..69c8dde6 100644 --- a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/main/MainBottomBar.kt +++ b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/main/MainBottomBar.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/main/MainContent.kt b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/main/MainContent.kt index ebecd8e2..da09e23f 100644 --- a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/main/MainContent.kt +++ b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/main/MainContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -35,8 +35,8 @@ package com.kodeco.learn.ui.main import androidx.compose.foundation.layout.Column -import androidx.compose.material.BottomSheetScaffoldState -import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.State @@ -54,7 +54,7 @@ import kotlinx.coroutines.CoroutineScope private val DEFAULT_SCREEN = BottomNavigationScreens.Home -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun MainContent( navController: NavHostController, @@ -79,7 +79,7 @@ fun MainContent( } } -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable private fun MainScreenNavigationConfigurations( navController: NavHostController, diff --git a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/main/MainScreen.kt b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/main/MainScreen.kt index 66964f83..4f17901a 100644 --- a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/main/MainScreen.kt +++ b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/main/MainScreen.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -37,9 +37,9 @@ package com.kodeco.learn.ui.main import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.BottomSheetScaffold -import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.rememberBottomSheetScaffoldState +import androidx.compose.material3.BottomSheetScaffold +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.rememberBottomSheetScaffoldState import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState @@ -58,7 +58,7 @@ import com.kodeco.learn.ui.home.HomeSheetContent private lateinit var selected: MutableState -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun MainScreen( profile: GravatarEntry?, diff --git a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/main/MainTopAppBar.kt b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/main/MainTopAppBar.kt index 15e0d6e5..65e05449 100644 --- a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/main/MainTopAppBar.kt +++ b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/main/MainTopAppBar.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -71,15 +71,15 @@ fun MainTopAppBar( val avatarUrl = profile?.thumbnailUrl if (avatarUrl == null) { Icon( - imageVector = Icons.Filled.Person, - contentDescription = stringResource(R.string.description_profile) + imageVector = Icons.Filled.Person, + contentDescription = stringResource(R.string.description_profile) ) } else { AddImagePreview( - url = avatarUrl, - modifier = Modifier - .clip(CircleShape) - .size(25.dp) + url = avatarUrl, + modifier = Modifier + .clip(CircleShape) + .size(25.dp) ) } } diff --git a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/search/SearchContent.kt b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/search/SearchContent.kt index f0685e21..137399c8 100644 --- a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/search/SearchContent.kt +++ b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/search/SearchContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,8 +38,8 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.material.BottomSheetScaffoldState -import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Surface @@ -63,7 +63,7 @@ import kotlinx.coroutines.CoroutineScope private const val TAG = "SearchContent" -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun SearchContent( selected: MutableState, diff --git a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/theme/Color.kt b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/theme/Color.kt index a594ad49..2e781c25 100644 --- a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/theme/Color.kt +++ b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/theme/Color.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/theme/Shape.kt b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/theme/Shape.kt index 8964a873..329ab7f5 100644 --- a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/theme/Shape.kt +++ b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/theme/Shape.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/theme/Theme.kt b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/theme/Theme.kt index 0fd73cb6..b59eedd4 100644 --- a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/theme/Theme.kt +++ b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/theme/Theme.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -35,6 +35,7 @@ package com.kodeco.learn.ui.theme import android.app.Activity +import android.os.Build import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.material3.MaterialTheme import androidx.compose.material3.darkColorScheme @@ -46,27 +47,28 @@ import androidx.compose.ui.platform.LocalView import androidx.core.view.WindowCompat private val DarkColorScheme = darkColorScheme( - primary = darkTextPrimary, - surface = darkBackground, - onSurfaceVariant = darkTextPrimary, - background = darkBackground, - secondaryContainer = darkSecondaryContainer, - onSecondaryContainer = darkBackground + primary = darkTextPrimary, + surface = darkBackground, + onSurfaceVariant = darkTextPrimary, + background = darkBackground, + secondaryContainer = darkSecondaryContainer, + onSecondaryContainer = darkBackground ) private val LightColorScheme = lightColorScheme( - primary = lightTextPrimary, - surface = lightBackground, - onSurfaceVariant = lightTextPrimary, - background = lightBackground, - secondaryContainer = lightSecondaryContainer, - onSecondaryContainer = lightBackground + primary = lightTextPrimary, + surface = lightBackground, + onSurfaceVariant = lightTextPrimary, + background = lightBackground, + secondaryContainer = lightSecondaryContainer, + onSecondaryContainer = lightBackground ) +@Suppress("DEPRECATION") @Composable fun KodecoTheme( - darkTheme: Boolean = isSystemInDarkTheme(), - content: @Composable () -> Unit + darkTheme: Boolean = isSystemInDarkTheme(), + content: @Composable () -> Unit ) { val colorScheme = when { darkTheme -> DarkColorScheme @@ -77,14 +79,21 @@ fun KodecoTheme( if (!view.isInEditMode) { SideEffect { val window = (view.context as Activity).window - window.statusBarColor = colorScheme.surface.toArgb() + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) { + window.decorView.setOnApplyWindowInsetsListener { view, insets -> + view.setBackgroundColor(colorScheme.surface.toArgb()) + insets + } + } else { + window.statusBarColor = colorScheme.surface.toArgb() + } WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !darkTheme } } MaterialTheme( - colorScheme = colorScheme, - typography = Typography, - content = content + colorScheme = colorScheme, + typography = Typography, + content = content ) } \ No newline at end of file diff --git a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/theme/Type.kt b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/theme/Type.kt index 5c500810..a5ef1f0b 100644 --- a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/theme/Type.kt +++ b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/theme/Type.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -90,5 +90,39 @@ val Typography = Typography( bodySmall = TextStyle( fontFamily = OpenSansFontFamily, fontSize = fontSizeSmall + ), + + titleLarge = TextStyle( + fontFamily = OpenSansFontFamily, + fontWeight = FontWeight.Normal, + fontSize = fontSizeBig + ), + + titleMedium = TextStyle( + fontFamily = OpenSansFontFamily, + fontWeight = FontWeight.Bold, + fontSize = fontSizeSmall + ), + + titleSmall = TextStyle( + fontFamily = OpenSansFontFamily, + fontSize = fontSizeSmall + ), + + labelLarge = TextStyle( + fontFamily = OpenSansFontFamily, + fontWeight = FontWeight.Normal, + fontSize = fontSizeBig + ), + + labelMedium = TextStyle( + fontFamily = OpenSansFontFamily, + fontWeight = FontWeight.Bold, + fontSize = fontSizeSmall + ), + + labelSmall = TextStyle( + fontFamily = OpenSansFontFamily, + fontSize = fontSizeSmall ) ) \ No newline at end of file diff --git a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/utils/Utils.kt b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/utils/Utils.kt index ce66defb..b0cec1fc 100644 --- a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/utils/Utils.kt +++ b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/utils/Utils.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -36,7 +36,7 @@ package com.kodeco.learn.utils import android.annotation.SuppressLint import com.kodeco.learn.platform.Logger -import kotlinx.datetime.toInstant +import kotlinx.datetime.Instant import java.text.SimpleDateFormat import java.util.* @@ -47,7 +47,7 @@ private val simpleDateFormat = SimpleDateFormat("yyyy/MM/dd", Locale.getDefault( fun converterIso8601ToReadableDate(date: String): String { return try { - val instant = date.toInstant() + val instant = Instant.parse(date) val millis = Date(instant.toEpochMilliseconds()) return simpleDateFormat.format(millis) } catch (e: Exception) { diff --git a/12-networking/projects/challenge/build.gradle.kts b/12-networking/projects/challenge/build.gradle.kts index f9602113..8d1115ba 100644 --- a/12-networking/projects/challenge/build.gradle.kts +++ b/12-networking/projects/challenge/build.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,15 +32,14 @@ * THE SOFTWARE. */ -// Top-level build file where you can add configuration options common to all sub-projects/modules. -@Suppress("DSL_SCOPE_VIOLATION") plugins { alias(libs.plugins.android.application) apply false alias(libs.plugins.android.library) apply false + alias(libs.plugins.jetbrains.compose.compiler) apply false alias(libs.plugins.jetbrains.kotlin) apply false alias(libs.plugins.jetbrains.kotlin.multiplatform) apply false - alias(libs.plugins.jetbrains.kotlin.parcelize) apply false alias(libs.plugins.jetbrains.kotlin.serialization) apply false + alias(libs.plugins.jetbrains.kotlin.parcelize) apply false alias(libs.plugins.cash.sqldelight) apply false } diff --git a/12-networking/projects/challenge/desktopApp/build.gradle.kts b/12-networking/projects/challenge/desktopApp/build.gradle.kts index 1515c5ed..40b47c25 100644 --- a/12-networking/projects/challenge/desktopApp/build.gradle.kts +++ b/12-networking/projects/challenge/desktopApp/build.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -33,41 +33,50 @@ */ import org.jetbrains.compose.desktop.application.dsl.TargetFormat +import org.jetbrains.kotlin.gradle.dsl.JvmTarget plugins { alias(libs.plugins.jetbrains.kotlin.multiplatform) + alias(libs.plugins.jetbrains.compose) + alias(libs.plugins.jetbrains.compose.compiler) } kotlin { jvm { compilations.all { - kotlinOptions.jvmTarget = "17" + compileTaskProvider.configure { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_17) + } + } } } sourceSets { - getByName("jvmMain") { - dependencies { - implementation(project(":shared")) + commonMain.dependencies { + implementation(compose.components.resources) + } - implementation(compose.desktop.currentOs) + jvmMain.dependencies { + implementation(project(":shared")) - implementation(compose.foundation) - implementation(compose.runtime) - implementation(compose.foundation) - implementation(compose.material) - implementation(compose.material3) - implementation(compose.ui) + implementation(compose.desktop.currentOs) - implementation(libs.kotlinx.datetime) + implementation(compose.foundation) + implementation(compose.runtime) + implementation(compose.foundation) + implementation(compose.material) + implementation(compose.material3) + implementation(compose.material3AdaptiveNavigationSuite) + implementation(compose.ui) - implementation(libs.image.loader) + implementation(libs.kotlinx.datetime) - implementation(libs.precompose) - implementation(libs.precompose.viewmodel) - } + implementation(libs.image.loader) + + implementation(libs.jetbrains.compose.lifecycle) } } } @@ -79,7 +88,7 @@ compose.desktop { nativeDistributions { targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb) packageName = "learn" - packageVersion = "2.0.0" + packageVersion = "3.0.0" val resources = project.layout.projectDirectory.dir("src/jvmMain/resources") appResourcesRootDir.set(resources) @@ -98,4 +107,9 @@ compose.desktop { } } } +} + +compose.resources { + publicResClass = true + packageOfResClass = "com.kodeco.learn.resources" } \ No newline at end of file diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/resources/images/ic_bookmarks.xml b/12-networking/projects/challenge/desktopApp/src/commonMain/composeResources/drawable/ic_bookmarks.xml similarity index 100% rename from 12-networking/projects/challenge/desktopApp/src/jvmMain/resources/images/ic_bookmarks.xml rename to 12-networking/projects/challenge/desktopApp/src/commonMain/composeResources/drawable/ic_bookmarks.xml diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/resources/images/ic_brand.xml b/12-networking/projects/challenge/desktopApp/src/commonMain/composeResources/drawable/ic_brand.xml similarity index 100% rename from 12-networking/projects/challenge/desktopApp/src/jvmMain/resources/images/ic_brand.xml rename to 12-networking/projects/challenge/desktopApp/src/commonMain/composeResources/drawable/ic_brand.xml diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/resources/images/ic_home.xml b/12-networking/projects/challenge/desktopApp/src/commonMain/composeResources/drawable/ic_home.xml similarity index 100% rename from 12-networking/projects/challenge/desktopApp/src/jvmMain/resources/images/ic_home.xml rename to 12-networking/projects/challenge/desktopApp/src/commonMain/composeResources/drawable/ic_home.xml diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/resources/images/ic_latest.xml b/12-networking/projects/challenge/desktopApp/src/commonMain/composeResources/drawable/ic_latest.xml similarity index 100% rename from 12-networking/projects/challenge/desktopApp/src/jvmMain/resources/images/ic_latest.xml rename to 12-networking/projects/challenge/desktopApp/src/commonMain/composeResources/drawable/ic_latest.xml diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/resources/images/ic_more.xml b/12-networking/projects/challenge/desktopApp/src/commonMain/composeResources/drawable/ic_more.xml similarity index 100% rename from 12-networking/projects/challenge/desktopApp/src/jvmMain/resources/images/ic_more.xml rename to 12-networking/projects/challenge/desktopApp/src/commonMain/composeResources/drawable/ic_more.xml diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/resources/images/ic_search.xml b/12-networking/projects/challenge/desktopApp/src/commonMain/composeResources/drawable/ic_search.xml similarity index 100% rename from 12-networking/projects/challenge/desktopApp/src/jvmMain/resources/images/ic_search.xml rename to 12-networking/projects/challenge/desktopApp/src/commonMain/composeResources/drawable/ic_search.xml diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/resources/font/opensans_bold.ttf b/12-networking/projects/challenge/desktopApp/src/commonMain/composeResources/font/opensans_bold.ttf similarity index 100% rename from 12-networking/projects/challenge/desktopApp/src/jvmMain/resources/font/opensans_bold.ttf rename to 12-networking/projects/challenge/desktopApp/src/commonMain/composeResources/font/opensans_bold.ttf diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/resources/font/opensans_extrabold.ttf b/12-networking/projects/challenge/desktopApp/src/commonMain/composeResources/font/opensans_extrabold.ttf similarity index 100% rename from 12-networking/projects/challenge/desktopApp/src/jvmMain/resources/font/opensans_extrabold.ttf rename to 12-networking/projects/challenge/desktopApp/src/commonMain/composeResources/font/opensans_extrabold.ttf diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/resources/font/opensans_light.ttf b/12-networking/projects/challenge/desktopApp/src/commonMain/composeResources/font/opensans_light.ttf similarity index 100% rename from 12-networking/projects/challenge/desktopApp/src/jvmMain/resources/font/opensans_light.ttf rename to 12-networking/projects/challenge/desktopApp/src/commonMain/composeResources/font/opensans_light.ttf diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/resources/font/opensans_regular.ttf b/12-networking/projects/challenge/desktopApp/src/commonMain/composeResources/font/opensans_regular.ttf similarity index 100% rename from 12-networking/projects/challenge/desktopApp/src/jvmMain/resources/font/opensans_regular.ttf rename to 12-networking/projects/challenge/desktopApp/src/commonMain/composeResources/font/opensans_regular.ttf diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/resources/font/opensans_semibold.ttf b/12-networking/projects/challenge/desktopApp/src/commonMain/composeResources/font/opensans_semibold.ttf similarity index 100% rename from 12-networking/projects/challenge/desktopApp/src/jvmMain/resources/font/opensans_semibold.ttf rename to 12-networking/projects/challenge/desktopApp/src/commonMain/composeResources/font/opensans_semibold.ttf diff --git a/12-networking/projects/challenge/desktopApp/src/commonMain/composeResources/values/strings.xml b/12-networking/projects/challenge/desktopApp/src/commonMain/composeResources/values/strings.xml new file mode 100644 index 00000000..c9820921 --- /dev/null +++ b/12-networking/projects/challenge/desktopApp/src/commonMain/composeResources/values/strings.xml @@ -0,0 +1,36 @@ + + learn + Kodeco + + + Home + Bookmark + Latest + Search + + + You currently don\'t have any bookmark. + Loading… + + + Search + + + Hello %s! + + Add to bookmarks + Remove from bookmarks + Share as link + Hey! Check out this article that I\'ve just found: %s. + + Added to bookmarks! + Removed from bookmarks + + + Search for a specific article + Feed icon + More actions + Image preview + Unable to load image preview + User profile + \ No newline at end of file diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/Main.kt b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/Main.kt index 7b46d332..8bf0bd83 100644 --- a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/Main.kt +++ b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/Main.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,16 +38,19 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material.Surface import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Window import androidx.compose.ui.window.application import androidx.compose.ui.window.rememberWindowState +import androidx.lifecycle.viewmodel.compose.viewModel import com.kodeco.learn.data.model.KodecoEntry import com.kodeco.learn.platform.Logger +import com.kodeco.learn.resources.Res +import com.kodeco.learn.resources.app_name import com.kodeco.learn.ui.bookmark.BookmarkViewModel import com.kodeco.learn.ui.home.FeedViewModel import com.kodeco.learn.ui.main.MainScreen import com.kodeco.learn.ui.theme.KodecoTheme -import moe.tlaster.precompose.PreComposeWindow -import moe.tlaster.precompose.viewmodel.viewModel +import org.jetbrains.compose.resources.stringResource import java.awt.Desktop import java.net.URI @@ -61,10 +64,10 @@ fun main() { application { val windowState = rememberWindowState(width = 460.dp, height = 900.dp) - PreComposeWindow( + Window( onCloseRequest = ::exitApplication, state = windowState, - title = "learn" + title = stringResource(Res.string.app_name) ) { bookmarkViewModel = viewModel { BookmarkViewModel() diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/components/ImagePreview.kt b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/components/ImagePreview.kt index 5aa04a0a..21065c38 100644 --- a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/components/ImagePreview.kt +++ b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/components/ImagePreview.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -45,9 +45,14 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.res.painterResource import com.kodeco.learn.platform.Logger +import com.kodeco.learn.resources.Res +import com.kodeco.learn.resources.description_preview +import com.kodeco.learn.resources.description_preview_error +import com.kodeco.learn.resources.ic_brand import com.seiko.imageloader.rememberImagePainter +import org.jetbrains.compose.resources.painterResource +import org.jetbrains.compose.resources.stringResource private const val TAG = "ImagePreview" @@ -65,8 +70,7 @@ fun AddImagePreview( } else { Box { - - val resource = painterResource("images/ic_brand.xml") + val resource = painterResource(Res.drawable.ic_brand) val painter = rememberImagePainter( url = url, @@ -77,7 +81,7 @@ fun AddImagePreview( Image( painter = painter, contentScale = ContentScale.Crop, - contentDescription = "Image preview", + contentDescription = stringResource(Res.string.description_preview), modifier = modifier ) } @@ -100,8 +104,8 @@ fun AddImagePreviewEmpty( color = Color.Transparent ) { - val resource = painterResource("images/ic_brand.xml") - val description = "Unable to load image preview" + val resource = painterResource(Res.drawable.ic_brand) + val description = stringResource(Res.string.description_preview_error) Column( horizontalAlignment = Alignment.CenterHorizontally, diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/bookmark/BookmarkContent.kt b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/bookmark/BookmarkContent.kt index b4812196..1c4f50c9 100644 --- a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/bookmark/BookmarkContent.kt +++ b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/bookmark/BookmarkContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/bookmark/BookmarkViewModel.kt b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/bookmark/BookmarkViewModel.kt index 28b42d5b..4a9a10b6 100644 --- a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/bookmark/BookmarkViewModel.kt +++ b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/bookmark/BookmarkViewModel.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -36,6 +36,8 @@ package com.kodeco.learn.ui.bookmark import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope import com.kodeco.learn.ServiceLocator import com.kodeco.learn.data.model.KodecoEntry import com.kodeco.learn.domain.cb.BookmarkData @@ -43,8 +45,6 @@ import com.kodeco.learn.platform.Logger import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import moe.tlaster.precompose.viewmodel.ViewModel -import moe.tlaster.precompose.viewmodel.viewModelScope private const val TAG = "BookmarkViewModel" diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/common/EmptyContent.kt b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/common/EmptyContent.kt index bd221c2d..ba7b331f 100644 --- a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/common/EmptyContent.kt +++ b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/common/EmptyContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/common/EntryContent.kt b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/common/EntryContent.kt index 8258206a..f00ea9a8 100644 --- a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/common/EntryContent.kt +++ b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/common/EntryContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -47,7 +47,7 @@ import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.BottomSheetScaffoldState import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material3.Divider +import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -55,15 +55,20 @@ import androidx.compose.runtime.MutableState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip -import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.kodeco.learn.components.AddImagePreview import com.kodeco.learn.data.model.KodecoEntry import com.kodeco.learn.platform.Logger +import com.kodeco.learn.resources.Res +import com.kodeco.learn.resources.app_kodeco +import com.kodeco.learn.resources.description_more +import com.kodeco.learn.resources.ic_more import com.kodeco.learn.utils.converterIso8601ToReadableDate import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch +import org.jetbrains.compose.resources.painterResource +import org.jetbrains.compose.resources.stringResource private const val TAG = "EntryContent" @@ -118,7 +123,7 @@ fun AddEntryContent( ) { Text( - text = "Kodeco" + text = stringResource(Res.string.app_kodeco) ) Text( @@ -132,8 +137,8 @@ fun AddEntryContent( horizontalArrangement = Arrangement.End ) { - val resource = painterResource("images/ic_more.xml") - val description = "More actions" + val resource = painterResource(Res.drawable.ic_more) + val description = stringResource(Res.string.description_more) Icon( painter = resource, @@ -167,7 +172,7 @@ fun AddEntryContent( Spacer(modifier = Modifier.height(16.dp)) if (divider) { - Divider( + HorizontalDivider( modifier = Modifier.fillMaxWidth(), thickness = 1.dp ) diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/FeedViewModel.kt b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/FeedViewModel.kt index dc420fc0..bef56617 100644 --- a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/FeedViewModel.kt +++ b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/FeedViewModel.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,6 +38,8 @@ import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateMapOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.snapshots.SnapshotStateMap +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope import com.kodeco.learn.ServiceLocator import com.kodeco.learn.data.model.GravatarEntry import com.kodeco.learn.data.model.KodecoEntry @@ -45,8 +47,6 @@ import com.kodeco.learn.data.model.PLATFORM import com.kodeco.learn.domain.cb.FeedData import com.kodeco.learn.platform.Logger import kotlinx.coroutines.launch -import moe.tlaster.precompose.viewmodel.ViewModel -import moe.tlaster.precompose.viewmodel.viewModelScope private const val TAG = "FeedViewModel" diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/HomeContent.kt b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/HomeContent.kt index 99dd0f0d..30a13cbc 100644 --- a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/HomeContent.kt +++ b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/HomeContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/HomeSheetContent.kt b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/HomeSheetContent.kt index 3dcc478c..454cc983 100644 --- a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/HomeSheetContent.kt +++ b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/home/HomeSheetContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -48,8 +48,13 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.kodeco.learn.data.model.KodecoEntry import com.kodeco.learn.platform.Logger +import com.kodeco.learn.resources.Res +import com.kodeco.learn.resources.action_add_bookmarks +import com.kodeco.learn.resources.action_remove_bookmarks +import com.kodeco.learn.resources.action_share_link import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch +import org.jetbrains.compose.resources.stringResource private const val TAG = "HomeSheetContent" @@ -82,9 +87,9 @@ fun HomeSheetContent( ) { val text = if (item.value.bookmarked) { - "Remove from bookmarks" + stringResource(Res.string.action_remove_bookmarks) } else { - "Add to bookmarks" + stringResource(Res.string.action_add_bookmarks) } Text( @@ -107,7 +112,7 @@ fun HomeSheetContent( } ) { Text( - text = "Share as link", + text = stringResource(Res.string.action_share_link), modifier = Modifier .fillMaxWidth() .padding(start = 16.dp, top = 12.dp, end = 16.dp, bottom = 24.dp) diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/latest/LatestContent.kt b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/latest/LatestContent.kt index fa2e9f5f..f88cd468 100644 --- a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/latest/LatestContent.kt +++ b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/latest/LatestContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/BottomNavigationScreens.kt b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/BottomNavigationScreens.kt index 14220282..83b09871 100644 --- a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/BottomNavigationScreens.kt +++ b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/BottomNavigationScreens.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -36,54 +36,65 @@ package com.kodeco.learn.ui.main import androidx.compose.material3.Icon import androidx.compose.runtime.Composable -import androidx.compose.ui.res.painterResource +import com.kodeco.learn.resources.Res +import com.kodeco.learn.resources.ic_bookmarks +import com.kodeco.learn.resources.ic_home +import com.kodeco.learn.resources.ic_latest +import com.kodeco.learn.resources.ic_search +import com.kodeco.learn.resources.navigation_bookmark +import com.kodeco.learn.resources.navigation_home +import com.kodeco.learn.resources.navigation_latest +import com.kodeco.learn.resources.navigation_search +import org.jetbrains.compose.resources.StringResource +import org.jetbrains.compose.resources.painterResource +import org.jetbrains.compose.resources.stringResource sealed class BottomNavigationScreens( val route: String, - val title: String, + val title: StringResource, val icon: @Composable () -> Unit ) { data object Home : BottomNavigationScreens( route = "Home", - title = "Home", + title = Res.string.navigation_home, icon = { Icon( - painter = painterResource("images/ic_home.xml"), - contentDescription = "Home" + painter = painterResource(Res.drawable.ic_home), + contentDescription = stringResource(Res.string.navigation_home) ) } ) data object Bookmark : BottomNavigationScreens( route = "Bookmark", - title = "Bookmark", + title = Res.string.navigation_bookmark, icon = { Icon( - painter = painterResource("images/ic_bookmarks.xml"), - contentDescription = "Bookmark" + painter = painterResource(Res.drawable.ic_bookmarks), + contentDescription = stringResource(Res.string.navigation_bookmark) ) } ) data object Latest : BottomNavigationScreens( route = "Latest", - title = "Latest", + title = Res.string.navigation_latest, icon = { Icon( - painter = painterResource("images/ic_latest.xml"), - contentDescription = "Latest" + painter = painterResource(Res.drawable.ic_latest), + contentDescription = stringResource(Res.string.navigation_latest) ) } ) data object Search : BottomNavigationScreens( route = "Search", - title = "Search", + title = Res.string.navigation_search, icon = { Icon( - painter = painterResource("images/ic_search.xml"), - contentDescription = "Search" + painter = painterResource(Res.drawable.ic_search), + contentDescription = stringResource(Res.string.navigation_search) ) } ) diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainBottomBar.kt b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainBottomBar.kt deleted file mode 100644 index 9a0aa349..00000000 --- a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainBottomBar.kt +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2023 Kodeco Inc - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, - * distribute, sublicense, create a derivative work, and/or sell copies of the - * Software in any work that is designed, intended, or marketed for pedagogical or - * instructional purposes related to programming, coding, application development, - * or information technology. Permission for such use, copying, modification, - * merger, publication, distribution, sublicensing, creation of derivative works, - * or sale is expressly withheld. - * - * This project and source code may use libraries or frameworks that are - * released under various Open-Source licenses. Use of those libraries and - * frameworks are governed by their own individual licenses. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.kodeco.learn.ui.main - -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.material3.BottomAppBar -import androidx.compose.material3.NavigationBarItem -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState -import androidx.compose.runtime.mutableIntStateOf -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import moe.tlaster.precompose.navigation.Navigator - -private lateinit var selectedIndex: MutableState - -@Composable -fun MainBottomBar( - navController: Navigator, - items: List -) { - - Column { - Row( - modifier = Modifier - .fillMaxWidth() - .height(1.dp) - ) {} - - AppBottomNavigation( - navController = navController, - items = items - ) - } -} - -@Composable -private fun AppBottomNavigation( - navController: Navigator, - items: List -) { - BottomAppBar { - - selectedIndex = remember { mutableIntStateOf(0) } - - items.forEachIndexed { index, screen -> - - val isSelected = selectedIndex.value == index - - NavigationBarItem( - icon = { - screen.icon() - }, - label = { - Text( - text = screen.title - ) - }, - selected = isSelected, - alwaysShowLabel = true, - onClick = { - if (!isSelected) { - selectedIndex.value = index - navController.navigate(screen.route) - } - } - ) - } - } -} \ No newline at end of file diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainContent.kt b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainContent.kt index fd19e217..14f2a144 100644 --- a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainContent.kt +++ b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -48,15 +48,11 @@ import com.kodeco.learn.ui.home.HomeContent import com.kodeco.learn.ui.latest.LatestContent import com.kodeco.learn.ui.search.SearchContent import kotlinx.coroutines.CoroutineScope -import moe.tlaster.precompose.navigation.NavHost -import moe.tlaster.precompose.navigation.Navigator - -private val DEFAULT_SCREEN = BottomNavigationScreens.Home @OptIn(ExperimentalMaterialApi::class) @Composable fun MainContent( - navController: Navigator, + destination: BottomNavigationScreens, coroutineScope: CoroutineScope, bottomSheetScaffoldState: BottomSheetScaffoldState, selected: MutableState, @@ -67,7 +63,7 @@ fun MainContent( Column { MainScreenNavigationConfigurations( - navController = navController, + destination = destination, coroutineScope = coroutineScope, bottomSheetScaffoldState = bottomSheetScaffoldState, selected = selected, @@ -81,7 +77,7 @@ fun MainContent( @OptIn(ExperimentalMaterialApi::class) @Composable private fun MainScreenNavigationConfigurations( - navController: Navigator, + destination: BottomNavigationScreens, coroutineScope: CoroutineScope, bottomSheetScaffoldState: BottomSheetScaffoldState, selected: MutableState, @@ -90,41 +86,38 @@ private fun MainScreenNavigationConfigurations( onOpenEntry: (String) -> Unit ) { - NavHost( - navigator = navController, - initialRoute = DEFAULT_SCREEN.route - ) { - scene(BottomNavigationScreens.Home.route) { + when(destination) { + BottomNavigationScreens.Home -> { HomeContent( - selected = selected, - items = feeds, - coroutineScope = coroutineScope, - bottomSheetScaffoldState = bottomSheetScaffoldState, - onOpenEntry = onOpenEntry + selected = selected, + items = feeds, + coroutineScope = coroutineScope, + bottomSheetScaffoldState = bottomSheetScaffoldState, + onOpenEntry = onOpenEntry ) } - scene(BottomNavigationScreens.Bookmark.route) { + BottomNavigationScreens.Bookmark -> { BookmarkContent( - selected = selected, - items = bookmarks, - coroutineScope = coroutineScope, - bottomSheetScaffoldState = bottomSheetScaffoldState, - onOpenEntry = onOpenEntry + selected = selected, + items = bookmarks, + coroutineScope = coroutineScope, + bottomSheetScaffoldState = bottomSheetScaffoldState, + onOpenEntry = onOpenEntry ) } - scene(BottomNavigationScreens.Latest.route) { + BottomNavigationScreens.Latest -> { LatestContent( - items = feeds, - onOpenEntry = onOpenEntry + items = feeds, + onOpenEntry = onOpenEntry ) } - scene(BottomNavigationScreens.Search.route) { + BottomNavigationScreens.Search -> { SearchContent( - selected = selected, - items = feeds, - coroutineScope = coroutineScope, - bottomSheetScaffoldState = bottomSheetScaffoldState, - onOpenEntry = onOpenEntry + selected = selected, + items = feeds, + coroutineScope = coroutineScope, + bottomSheetScaffoldState = bottomSheetScaffoldState, + onOpenEntry = onOpenEntry ) } } diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainScreen.kt b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainScreen.kt index 1fc49b25..7051161d 100644 --- a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainScreen.kt +++ b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainScreen.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -40,7 +40,8 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.BottomSheetScaffold import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.rememberBottomSheetScaffoldState -import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteScaffold import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.State @@ -54,8 +55,9 @@ import com.kodeco.learn.data.model.GravatarEntry import com.kodeco.learn.data.model.KodecoEntry import com.kodeco.learn.data.model.PLATFORM import com.kodeco.learn.ui.home.HomeSheetContent -import moe.tlaster.precompose.navigation.rememberNavigator +import org.jetbrains.compose.resources.stringResource +private val DEFAULT_SCREEN = BottomNavigationScreens.Home private lateinit var selected: MutableState @OptIn(ExperimentalMaterialApi::class) @@ -76,7 +78,9 @@ fun MainScreen( BottomNavigationScreens.Search ) - val navController = rememberNavigator() + val currentDestination = remember { + mutableStateOf(DEFAULT_SCREEN) + } val coroutineScope = rememberCoroutineScope() val bottomSheetScaffoldState = rememberBottomSheetScaffoldState() @@ -100,33 +104,42 @@ fun MainScreen( scaffoldState = bottomSheetScaffoldState, sheetPeekHeight = 0.dp ) { - Scaffold( - topBar = { + NavigationSuiteScaffold( + navigationSuiteItems = { + bottomNavigationItems.forEach { screen -> + item( + icon = { + screen.icon() + }, + label = { + Text( + text = stringResource(screen.title) + ) + }, + selected = screen == currentDestination.value, + onClick = { currentDestination.value = screen } + ) + } + }, + content = { + Column( + modifier = Modifier.padding(it) + ) { MainTopAppBar( - profile = profile + profile = profile ) - }, - bottomBar = { - MainBottomBar( - navController = navController, - items = bottomNavigationItems + + MainContent( + destination = currentDestination.value, + coroutineScope = coroutineScope, + bottomSheetScaffoldState = bottomSheetScaffoldState, + selected = selected, + feeds = feeds, + bookmarks = bookmarks, + onOpenEntry = onOpenEntry ) - }, - content = { - Column( - modifier = Modifier.padding(it) - ) { - MainContent( - navController = navController, - coroutineScope = coroutineScope, - bottomSheetScaffoldState = bottomSheetScaffoldState, - selected = selected, - feeds = feeds, - bookmarks = bookmarks, - onOpenEntry = onOpenEntry - ) - } } + } ) } } \ No newline at end of file diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainTopAppBar.kt b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainTopAppBar.kt index 605c5acd..97a009cd 100644 --- a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainTopAppBar.kt +++ b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/main/MainTopAppBar.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -49,17 +49,21 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.dp import com.kodeco.learn.components.AddImagePreview import com.kodeco.learn.data.model.GravatarEntry +import com.kodeco.learn.resources.Res +import com.kodeco.learn.resources.app_name +import com.kodeco.learn.resources.description_profile +import org.jetbrains.compose.resources.stringResource @OptIn(ExperimentalMaterial3Api::class) @Composable fun MainTopAppBar( - profile: GravatarEntry? + profile: GravatarEntry?, ) { CenterAlignedTopAppBar( title = { Text( - text = "learn" + text = stringResource(Res.string.app_name), ) }, actions = { @@ -69,15 +73,15 @@ fun MainTopAppBar( val avatarUrl = profile?.thumbnailUrl if (avatarUrl == null) { Icon( - imageVector = Icons.Filled.Person, - contentDescription = "User profile" + imageVector = Icons.Filled.Person, + contentDescription = stringResource(Res.string.description_profile) ) } else { AddImagePreview( - url = avatarUrl, - modifier = Modifier - .clip(CircleShape) - .size(25.dp) + url = avatarUrl, + modifier = Modifier + .clip(CircleShape) + .size(25.dp) ) } } diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/search/SearchContent.kt b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/search/SearchContent.kt index 4e2a4d00..b816f6b3 100644 --- a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/search/SearchContent.kt +++ b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/search/SearchContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -51,13 +51,15 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.snapshots.SnapshotStateMap import androidx.compose.ui.Modifier import androidx.compose.ui.focus.onFocusChanged -import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import com.kodeco.learn.data.model.KodecoEntry import com.kodeco.learn.data.model.PLATFORM import com.kodeco.learn.platform.Logger +import com.kodeco.learn.resources.Res +import com.kodeco.learn.resources.ic_search import com.kodeco.learn.ui.common.AddEntryContent import kotlinx.coroutines.CoroutineScope +import org.jetbrains.compose.resources.painterResource private const val TAG = "SearchContent" @@ -140,7 +142,7 @@ fun AddSearchField(search: MutableState) { ) }, leadingIcon = { - val resource = painterResource("images/ic_search.xml") + val resource = painterResource(Res.drawable.ic_search) val description = "Search for a specific article" Icon( diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Color.kt b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Color.kt index a594ad49..2e781c25 100644 --- a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Color.kt +++ b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Color.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Shape.kt b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Shape.kt index 8964a873..329ab7f5 100644 --- a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Shape.kt +++ b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Shape.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Theme.kt b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Theme.kt index 49e5b7eb..50c564f8 100644 --- a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Theme.kt +++ b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Theme.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -70,7 +70,7 @@ fun KodecoTheme( MaterialTheme( colorScheme = colorScheme, - typography = Typography, + typography = Typography(OpenSansFontFamily()), content = content ) } \ No newline at end of file diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Type.kt b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Type.kt index cd4e4933..48aa65b3 100644 --- a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Type.kt +++ b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/theme/Type.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -35,59 +35,102 @@ package com.kodeco.learn.ui.theme import androidx.compose.material3.Typography +import androidx.compose.runtime.Composable import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.platform.Font import androidx.compose.ui.unit.sp +import com.kodeco.learn.resources.Res +import com.kodeco.learn.resources.opensans_bold +import com.kodeco.learn.resources.opensans_extrabold +import com.kodeco.learn.resources.opensans_light +import com.kodeco.learn.resources.opensans_regular +import com.kodeco.learn.resources.opensans_semibold +import org.jetbrains.compose.resources.Font private val fontSizeBig = 16.sp private val fontSizeMedium = 15.sp private val fontSizeSmall = 14.sp private val fontSizeTiny = 12.sp -private val OpenSansFontFamily = FontFamily( - Font("font/opensans_bold.ttf", FontWeight.Bold), - Font("font/opensans_extrabold.ttf", FontWeight.ExtraBold), - Font("font/opensans_light.ttf", FontWeight.Light), - Font("font/opensans_regular.ttf", FontWeight.Normal), - Font("font/opensans_semibold.ttf", FontWeight.SemiBold), +@Composable +fun OpenSansFontFamily() = FontFamily( + Font(Res.font.opensans_bold, FontWeight.Bold, FontStyle.Normal), + Font(Res.font.opensans_extrabold, FontWeight.ExtraBold, FontStyle.Normal), + Font(Res.font.opensans_light, FontWeight.Light, FontStyle.Normal), + Font(Res.font.opensans_regular, FontWeight.Normal, FontStyle.Normal), + Font(Res.font.opensans_semibold, FontWeight.SemiBold, FontStyle.Normal) ) // Set of Material typography styles to start with -val Typography = Typography( +fun Typography(family: FontFamily) = Typography( headlineLarge = TextStyle( - fontFamily = OpenSansFontFamily, + fontFamily = family, fontWeight = FontWeight.Bold, fontSize = fontSizeMedium ), headlineMedium = TextStyle( - fontFamily = OpenSansFontFamily, + fontFamily = family, fontWeight = FontWeight.Normal, fontSize = fontSizeSmall ), headlineSmall = TextStyle( - fontFamily = OpenSansFontFamily, + fontFamily = family, fontWeight = FontWeight.Bold, fontSize = fontSizeTiny ), bodyLarge = TextStyle( - fontFamily = OpenSansFontFamily, + fontFamily = family, fontWeight = FontWeight.Normal, fontSize = fontSizeBig ), bodyMedium = TextStyle( - fontFamily = OpenSansFontFamily, + fontFamily = family, fontWeight = FontWeight.Bold, fontSize = fontSizeSmall ), bodySmall = TextStyle( - fontFamily = OpenSansFontFamily, + fontFamily = family, + fontSize = fontSizeSmall + ), + + titleLarge = TextStyle( + fontFamily = family, + fontWeight = FontWeight.Normal, + fontSize = fontSizeBig + ), + + titleMedium = TextStyle( + fontFamily = family, + fontWeight = FontWeight.Bold, + fontSize = fontSizeSmall + ), + + titleSmall = TextStyle( + fontFamily = family, + fontSize = fontSizeSmall + ), + + labelLarge = TextStyle( + fontFamily = family, + fontWeight = FontWeight.Normal, + fontSize = fontSizeBig + ), + + labelMedium = TextStyle( + fontFamily = family, + fontWeight = FontWeight.Bold, + fontSize = fontSizeSmall + ), + + labelSmall = TextStyle( + fontFamily = family, fontSize = fontSizeSmall ) ) \ No newline at end of file diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/utils/Utils.kt b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/utils/Utils.kt index a92d0ad1..6e58ae85 100644 --- a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/utils/Utils.kt +++ b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/utils/Utils.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -35,7 +35,7 @@ package com.kodeco.learn.utils import com.kodeco.learn.platform.Logger -import kotlinx.datetime.toInstant +import kotlinx.datetime.Instant import java.text.SimpleDateFormat import java.util.Date import java.util.Locale @@ -47,7 +47,7 @@ private val simpleDateFormat = SimpleDateFormat("yyyy/MM/dd", Locale.getDefault( fun converterIso8601ToReadableDate(date: String): String { return try { - val instant = date.toInstant() + val instant = Instant.parse(date) val millis = Date(instant.toEpochMilliseconds()) return simpleDateFormat.format(millis) } catch (e: Exception) { diff --git a/12-networking/projects/challenge/gradle.properties b/12-networking/projects/challenge/gradle.properties index 1677b55e..27359d2f 100644 --- a/12-networking/projects/challenge/gradle.properties +++ b/12-networking/projects/challenge/gradle.properties @@ -9,7 +9,6 @@ org.gradle.jvmargs=-Xmx6g -XX:+UseParallelGC # MPP kotlin.mpp.enableCInteropCommonization=true kotlin.mpp.stability.nowarn=true -kotlin.mpp.androidSourceSetLayoutVersion=2 # https://blog.jetbrains.com/kotlin/2022/07/a-new-approach-to-incremental-compilation-in-kotlin/ kotlin.incremental.useClasspathSnapshot=true diff --git a/12-networking/projects/challenge/gradle/libs.versions.toml b/12-networking/projects/challenge/gradle/libs.versions.toml index 877093de..5577f102 100644 --- a/12-networking/projects/challenge/gradle/libs.versions.toml +++ b/12-networking/projects/challenge/gradle/libs.versions.toml @@ -1,25 +1,23 @@ [versions] -gradle = "8.1.2" -android-sdk-compile = "34" +gradle = "8.8.0" +android-sdk-compile = "35" android-sdk-min = "24" -android-sdk-target = "34" -android-compose-compiler = "1.5.3" -android-material = "1.10.0" -androidx-compose-bom = "2023.10.00" -androidx-lifecycle-runtime-ktx = "2.6.2" -androidx-navigation-compose = "2.7.4" -coil = "2.4.0" -image-loader = "1.6.7" +android-sdk-target = "35" +android-material = "1.12.0" +androidx-compose-bom = "2025.01.01" +androidx-lifecycle-runtime-ktx = "2.8.7" +androidx-navigation-compose = "2.8.6" +coil = "2.7.0" +image-loader = "1.10.0" korio = "4.0.10" -kotlin = "1.9.10" -kotlinx-datetime = "0.4.1" -kotlinx-serialization-json = "1.6.0" -ktor = "2.3.4" -jetbrains-compose = "1.5.3" -junit = "4.13.2" -okio = "3.5.0" -precompose = "1.5.3" -sqldelight = "2.0.0" +kotlin = "2.1.0" +kotlinx-datetime = "0.6.1" +kotlinx-serialization-json = "1.7.3" +ktor = "3.0.3" +jetbrains-compose = "1.7.3" +jetbrains-compose-lifecycle = "2.8.0" +okio = "3.10.2" +sqldelight = "2.0.2" [libraries] android-material = { module = "com.google.android.material:material", version.ref = "android-material" } @@ -34,33 +32,33 @@ androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" } androidx-lifecycle-runtime-ktx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "androidx-lifecycle-runtime-ktx" } androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "androidx-navigation-compose" } +jetbrains-compose-lifecycle = { module = "org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "jetbrains-compose-lifecycle" } + cash-sqldelight-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" } cash-sqldelight-jvm = { module = "app.cash.sqldelight:sqlite-driver", version.ref = "sqldelight" } cash-sqldelight-native = { module = "app.cash.sqldelight:native-driver", version.ref = "sqldelight" } image-coil = { module = "io.coil-kt:coil-compose", version.ref = "coil" } image-loader = { module = "io.github.qdsfdhvh:image-loader", version.ref = "image-loader" } -junit = { module = "junit:junit", version.ref = "junit" } korio = { module = "com.soywiz.korlibs.korio:korio", version.ref = "korio" } kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinx-datetime" } kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization-json" } ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" } -ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" } ktor-client-serialization = { module = "io.ktor:ktor-client-serialization", version.ref = "ktor" } ktor-client-android = { module = "io.ktor:ktor-client-android", version.ref = "ktor" } ktor-client-ios = { module = "io.ktor:ktor-client-ios", version.ref = "ktor" } +ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" } +ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" } ktor-client-logging = { module = "io.ktor:ktor-client-logging", version.ref = "ktor" } ktor-client-mock = { module = "io.ktor:ktor-client-mock", version.ref = "ktor" } -ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" } okio = { module = "com.squareup.okio:okio", version.ref = "okio" } -precompose-viewmodel = { module = "moe.tlaster:precompose-viewmodel", version.ref = "precompose" } -precompose = { module = "moe.tlaster:precompose", version.ref = "precompose" } [plugins] android-application = { id = "com.android.application", version.ref = "gradle" } android-library = { id = "com.android.library", version.ref = "gradle" } cash-sqldelight = { id = "app.cash.sqldelight", version.ref = "sqldelight" } jetbrains-compose = { id = "org.jetbrains.compose", version.ref = "jetbrains-compose" } +jetbrains-compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } jetbrains-kotlin = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } jetbrains-kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } -jetbrains-kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" } jetbrains-kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } +jetbrains-kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" } \ No newline at end of file diff --git a/12-networking/projects/challenge/gradle/wrapper/gradle-wrapper.properties b/12-networking/projects/challenge/gradle/wrapper/gradle-wrapper.properties index 4b932409..5a450493 100644 --- a/12-networking/projects/challenge/gradle/wrapper/gradle-wrapper.properties +++ b/12-networking/projects/challenge/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Wed Jul 21 00:48:56 WEST 2021 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME diff --git a/12-networking/projects/challenge/iosApp/iosApp.xcodeproj/project.pbxproj b/12-networking/projects/challenge/iosApp/iosApp.xcodeproj/project.pbxproj index e524a599..f3346292 100644 --- a/12-networking/projects/challenge/iosApp/iosApp.xcodeproj/project.pbxproj +++ b/12-networking/projects/challenge/iosApp/iosApp.xcodeproj/project.pbxproj @@ -17,7 +17,7 @@ 670990692715023E0048A7B5 /* SearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 670990682715023E0048A7B5 /* SearchView.swift */; }; 6709909D2717ABF80048A7B5 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6709909C2717ABF80048A7B5 /* Utils.swift */; }; 6761C5672A9B4AD1008BB48B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6761C5662A9B4AD1008BB48B /* LaunchScreen.storyboard */; }; - 6763BD852AA6613400A70BAA /* MainToolbarContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6763BD842AA6613400A70BAA /* MainToolbarContent.swift */; }; + 6763BD882AA6B9CD00A70BAA /* MainToolbarContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6763BD872AA6B9CD00A70BAA /* MainToolbarContent.swift */; }; 67A1CBAB27ADFD27005629A1 /* Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67A1CBAA27ADFD27005629A1 /* Actions.swift */; }; 67BD5C082A9B555900FFDFEA /* SDWebImageSwiftUI in Frameworks */ = {isa = PBXBuildFile; productRef = 67BD5C072A9B555900FFDFEA /* SDWebImageSwiftUI */; }; 67C6FF262A98FC8D008A2221 /* KodecoEntryViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67C6FF252A98FC8D008A2221 /* KodecoEntryViewModel.swift */; }; @@ -41,8 +41,8 @@ 670990682715023E0048A7B5 /* SearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchView.swift; sourceTree = ""; }; 6709909C2717ABF80048A7B5 /* Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = ""; }; 6761C5662A9B4AD1008BB48B /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; - 6763BD832AA6402000A70BAA /* iosApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iosApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 6763BD842AA6613400A70BAA /* MainToolbarContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainToolbarContent.swift; sourceTree = ""; }; + 6763BD862AA6B93300A70BAA /* iosApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iosApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 6763BD872AA6B9CD00A70BAA /* MainToolbarContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainToolbarContent.swift; sourceTree = ""; }; 67A1CBAA27ADFD27005629A1 /* Actions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Actions.swift; sourceTree = ""; }; 67C6FF252A98FC8D008A2221 /* KodecoEntryViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KodecoEntryViewModel.swift; sourceTree = ""; }; 67C6FF292A98FD38008A2221 /* OpenSansBold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = OpenSansBold.ttf; sourceTree = ""; }; @@ -109,7 +109,7 @@ isa = PBXGroup; children = ( 7555FF7D242A565900829871 /* iosApp */, - 6763BD832AA6402000A70BAA /* iosApp.app */, + 6763BD862AA6B93300A70BAA /* iosApp.app */, ); sourceTree = ""; }; @@ -130,7 +130,7 @@ 670990682715023E0048A7B5 /* SearchView.swift */, 67C6FF252A98FC8D008A2221 /* KodecoEntryViewModel.swift */, 6761C5662A9B4AD1008BB48B /* LaunchScreen.storyboard */, - 6763BD842AA6613400A70BAA /* MainToolbarContent.swift */, + 6763BD872AA6B9CD00A70BAA /* MainToolbarContent.swift */, ); path = iosApp; sourceTree = ""; @@ -157,7 +157,7 @@ 67BD5C072A9B555900FFDFEA /* SDWebImageSwiftUI */, ); productName = iosApp; - productReference = 6763BD832AA6402000A70BAA /* iosApp.app */; + productReference = 6763BD862AA6B93300A70BAA /* iosApp.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ @@ -267,9 +267,9 @@ 67099063271501C00048A7B5 /* HomeView.swift in Sources */, 6709909D2717ABF80048A7B5 /* Utils.swift in Sources */, 67C6FF342A98FD95008A2221 /* KodecoEntryRow.swift in Sources */, + 6763BD882AA6B9CD00A70BAA /* MainToolbarContent.swift in Sources */, 7555FF83242A565900829871 /* ContentView.swift in Sources */, 67A1CBAB27ADFD27005629A1 /* Actions.swift in Sources */, - 6763BD852AA6613400A70BAA /* MainToolbarContent.swift in Sources */, 67C6FF262A98FC8D008A2221 /* KodecoEntryViewModel.swift in Sources */, 67099067271502210048A7B5 /* LatestView.swift in Sources */, ); diff --git a/12-networking/projects/challenge/iosApp/iosApp/BookmarkView.swift b/12-networking/projects/challenge/iosApp/iosApp/BookmarkView.swift index 41791b2c..2760077d 100644 --- a/12-networking/projects/challenge/iosApp/iosApp/BookmarkView.swift +++ b/12-networking/projects/challenge/iosApp/iosApp/BookmarkView.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal @@ -32,7 +32,6 @@ import SwiftUI import SharedKit -import SDWebImageSwiftUI struct BookmarkView: View { let TAG = "BookmarkView" diff --git a/12-networking/projects/challenge/iosApp/iosApp/ContentView.swift b/12-networking/projects/challenge/iosApp/iosApp/ContentView.swift index a067502c..233c88f6 100644 --- a/12-networking/projects/challenge/iosApp/iosApp/ContentView.swift +++ b/12-networking/projects/challenge/iosApp/iosApp/ContentView.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/iosApp/iosApp/HomeView.swift b/12-networking/projects/challenge/iosApp/iosApp/HomeView.swift index 43052702..4cb0245f 100644 --- a/12-networking/projects/challenge/iosApp/iosApp/HomeView.swift +++ b/12-networking/projects/challenge/iosApp/iosApp/HomeView.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/iosApp/iosApp/KodecoEntryViewModel.swift b/12-networking/projects/challenge/iosApp/iosApp/KodecoEntryViewModel.swift index 5239b41d..531e26e0 100644 --- a/12-networking/projects/challenge/iosApp/iosApp/KodecoEntryViewModel.swift +++ b/12-networking/projects/challenge/iosApp/iosApp/KodecoEntryViewModel.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/iosApp/iosApp/LatestView.swift b/12-networking/projects/challenge/iosApp/iosApp/LatestView.swift index 3b004330..e87ff438 100644 --- a/12-networking/projects/challenge/iosApp/iosApp/LatestView.swift +++ b/12-networking/projects/challenge/iosApp/iosApp/LatestView.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/iosApp/iosApp/MainToolbarContent.swift b/12-networking/projects/challenge/iosApp/iosApp/MainToolbarContent.swift index 51c10955..8fb616f5 100644 --- a/12-networking/projects/challenge/iosApp/iosApp/MainToolbarContent.swift +++ b/12-networking/projects/challenge/iosApp/iosApp/MainToolbarContent.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/iosApp/iosApp/SearchView.swift b/12-networking/projects/challenge/iosApp/iosApp/SearchView.swift index 2c4b4089..91be014e 100644 --- a/12-networking/projects/challenge/iosApp/iosApp/SearchView.swift +++ b/12-networking/projects/challenge/iosApp/iosApp/SearchView.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/iosApp/iosApp/common/KodecoEntryRow.swift b/12-networking/projects/challenge/iosApp/iosApp/common/KodecoEntryRow.swift index 600de5ba..087a489d 100644 --- a/12-networking/projects/challenge/iosApp/iosApp/common/KodecoEntryRow.swift +++ b/12-networking/projects/challenge/iosApp/iosApp/common/KodecoEntryRow.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal @@ -58,7 +58,6 @@ struct KodecoEntryRow: View { VStack(alignment: .leading) { HStack { if item.imageUrl.isEmpty { - Rectangle().foregroundColor(.gray) Image("kodeco") .resizable() .frame(width: 50, height: 50) diff --git a/12-networking/projects/challenge/iosApp/iosApp/extensions/BookmarkClient.swift b/12-networking/projects/challenge/iosApp/iosApp/extensions/BookmarkClient.swift index a962b101..6f2435ec 100644 --- a/12-networking/projects/challenge/iosApp/iosApp/extensions/BookmarkClient.swift +++ b/12-networking/projects/challenge/iosApp/iosApp/extensions/BookmarkClient.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/iosApp/iosApp/extensions/FeedClient.swift b/12-networking/projects/challenge/iosApp/iosApp/extensions/FeedClient.swift index 8bc0e718..dd07e43e 100644 --- a/12-networking/projects/challenge/iosApp/iosApp/extensions/FeedClient.swift +++ b/12-networking/projects/challenge/iosApp/iosApp/extensions/FeedClient.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/iosApp/iosApp/iOSApp.swift b/12-networking/projects/challenge/iosApp/iosApp/iOSApp.swift index ace71a32..868ad2fe 100644 --- a/12-networking/projects/challenge/iosApp/iosApp/iOSApp.swift +++ b/12-networking/projects/challenge/iosApp/iosApp/iOSApp.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/iosApp/iosApp/utils/Actions.swift b/12-networking/projects/challenge/iosApp/iosApp/utils/Actions.swift index 35253b96..1337bb35 100644 --- a/12-networking/projects/challenge/iosApp/iosApp/utils/Actions.swift +++ b/12-networking/projects/challenge/iosApp/iosApp/utils/Actions.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/iosApp/iosApp/utils/Utils.swift b/12-networking/projects/challenge/iosApp/iosApp/utils/Utils.swift index 4463f1f3..621ebcf4 100644 --- a/12-networking/projects/challenge/iosApp/iosApp/utils/Utils.swift +++ b/12-networking/projects/challenge/iosApp/iosApp/utils/Utils.swift @@ -1,4 +1,4 @@ -/// Copyright (c) 2023 Kodeco Inc +/// Copyright (c) 2025 Kodeco Inc /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/settings.gradle.kts b/12-networking/projects/challenge/settings.gradle.kts index 56713c61..97b54fa6 100644 --- a/12-networking/projects/challenge/settings.gradle.kts +++ b/12-networking/projects/challenge/settings.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared-dto/build.gradle.kts b/12-networking/projects/challenge/shared-dto/build.gradle.kts index 3deed4a4..23ab3b4d 100644 --- a/12-networking/projects/challenge/shared-dto/build.gradle.kts +++ b/12-networking/projects/challenge/shared-dto/build.gradle.kts @@ -1,53 +1,69 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + plugins { - kotlin("multiplatform") - id("com.android.library") - alias(libs.plugins.jetbrains.kotlin.parcelize) - alias(libs.plugins.jetbrains.kotlin.serialization) + kotlin("multiplatform") + id("com.android.library") + + alias(libs.plugins.jetbrains.kotlin.parcelize) + alias(libs.plugins.jetbrains.kotlin.serialization) } -@OptIn(org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi::class) kotlin { - targetHierarchy.default() - androidTarget() + androidTarget { + compilerOptions { + // Issue #KT-58892: https://youtrack.jetbrains.com/issue/KT-58892/K2-Parcelize-doesnt-work-in-common-code-when-expect-annotation-is-actualized-with-typealias-to-Parcelize + freeCompilerArgs.addAll("-P", "plugin:org.jetbrains.kotlin.parcelize:additionalAnnotation=com.kodeco.learn.platform.Parcelize") + } + compilations.all { + compileTaskProvider.configure { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_17) + } + } + } + } - jvm() + jvm() - listOf( - iosX64(), - iosArm64(), - iosSimulatorArm64() - ).forEach { - it.binaries.framework { - baseName = "shared-dto" - } + listOf( + iosX64(), + iosArm64(), + iosSimulatorArm64() + ).forEach { + it.binaries.framework { + baseName = "shared-dto" } + } - sourceSets { - getByName("commonMain") { - dependencies { - implementation(libs.kotlinx.serialization.json) - } - } - getByName("commonTest") { - dependencies { - implementation(kotlin("test")) - } - } + sourceSets { + commonMain { + dependencies { + implementation(libs.kotlinx.serialization.json) + } } + } } android { - namespace = "com.kodeco.shared" + namespace = "com.kodeco.shared" - compileSdk = 33 + compileSdk = libs.versions.android.sdk.compile.get().toInt() - defaultConfig { - minSdk = 24 - } + defaultConfig { + minSdk = libs.versions.android.sdk.min.get().toInt() + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } +} - compileOptions { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 +kotlin.targets.configureEach { + compilations.configureEach { + compileTaskProvider.get().compilerOptions { + freeCompilerArgs.add("-Xexpect-actual-classes") } + } } \ No newline at end of file diff --git a/12-networking/projects/challenge/shared-dto/src/androidMain/kotlin/com/kodeco/learn/platform/Parcelable.android.kt b/12-networking/projects/challenge/shared-dto/src/androidMain/kotlin/com/kodeco/learn/platform/Parcelable.android.kt index 1fc85362..fefdce70 100644 --- a/12-networking/projects/challenge/shared-dto/src/androidMain/kotlin/com/kodeco/learn/platform/Parcelable.android.kt +++ b/12-networking/projects/challenge/shared-dto/src/androidMain/kotlin/com/kodeco/learn/platform/Parcelable.android.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -35,4 +35,4 @@ package com.kodeco.learn.platform actual typealias Parcelable = android.os.Parcelable -actual typealias Parcelize = kotlinx.android.parcel.Parcelize \ No newline at end of file +actual typealias Parcelize = kotlinx.parcelize.Parcelize \ No newline at end of file diff --git a/12-networking/projects/challenge/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/KodecoSerializer.kt b/12-networking/projects/challenge/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/KodecoSerializer.kt index e3bc23dd..3c73cd9f 100644 --- a/12-networking/projects/challenge/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/KodecoSerializer.kt +++ b/12-networking/projects/challenge/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/KodecoSerializer.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -62,5 +62,5 @@ object KodecoSerializer : KSerializer { } private fun findByKey(key: String, default: PLATFORM = PLATFORM.ALL): PLATFORM { - return PLATFORM.values().find { it.value.lowercase() == key.lowercase() } ?: default + return PLATFORM.entries.find { it.value.lowercase() == key.lowercase() } ?: default } \ No newline at end of file diff --git a/12-networking/projects/challenge/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/GravatarContent.kt b/12-networking/projects/challenge/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/GravatarContent.kt index 3f93c73d..09160a3b 100644 --- a/12-networking/projects/challenge/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/GravatarContent.kt +++ b/12-networking/projects/challenge/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/GravatarContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/KodecoContent.kt b/12-networking/projects/challenge/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/KodecoContent.kt index 7f88308d..272cbcc9 100644 --- a/12-networking/projects/challenge/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/KodecoContent.kt +++ b/12-networking/projects/challenge/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/KodecoContent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/KodecoEntry.kt b/12-networking/projects/challenge/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/KodecoEntry.kt index bae3fe09..d028d2c8 100644 --- a/12-networking/projects/challenge/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/KodecoEntry.kt +++ b/12-networking/projects/challenge/shared-dto/src/commonMain/kotlin/com/kodeco/learn/data/model/KodecoEntry.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,8 +38,8 @@ import com.kodeco.learn.platform.Parcelable import com.kodeco.learn.platform.Parcelize import kotlinx.serialization.Serializable -@Serializable @Parcelize +@Serializable data class KodecoEntry( val id: String = "", val link: String = "", diff --git a/12-networking/projects/challenge/shared-dto/src/commonMain/kotlin/com/kodeco/learn/platform/Parcelable.common.kt b/12-networking/projects/challenge/shared-dto/src/commonMain/kotlin/com/kodeco/learn/platform/Parcelable.common.kt index eff22a1b..b2bc0d45 100644 --- a/12-networking/projects/challenge/shared-dto/src/commonMain/kotlin/com/kodeco/learn/platform/Parcelable.common.kt +++ b/12-networking/projects/challenge/shared-dto/src/commonMain/kotlin/com/kodeco/learn/platform/Parcelable.common.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared-dto/src/iosMain/kotlin/com/kodeco/learn/platform/Parcelable.ios.kt b/12-networking/projects/challenge/shared-dto/src/iosMain/kotlin/com/kodeco/learn/platform/Parcelable.ios.kt index 540759c2..86d99b50 100644 --- a/12-networking/projects/challenge/shared-dto/src/iosMain/kotlin/com/kodeco/learn/platform/Parcelable.ios.kt +++ b/12-networking/projects/challenge/shared-dto/src/iosMain/kotlin/com/kodeco/learn/platform/Parcelable.ios.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared-dto/src/jvmMain/kotlin/com/kodeco/learn/platform/Parcelable.desktop.kt b/12-networking/projects/challenge/shared-dto/src/jvmMain/kotlin/com/kodeco/learn/platform/Parcelable.jvm.kt similarity index 98% rename from 12-networking/projects/challenge/shared-dto/src/jvmMain/kotlin/com/kodeco/learn/platform/Parcelable.desktop.kt rename to 12-networking/projects/challenge/shared-dto/src/jvmMain/kotlin/com/kodeco/learn/platform/Parcelable.jvm.kt index 540759c2..86d99b50 100644 --- a/12-networking/projects/challenge/shared-dto/src/jvmMain/kotlin/com/kodeco/learn/platform/Parcelable.desktop.kt +++ b/12-networking/projects/challenge/shared-dto/src/jvmMain/kotlin/com/kodeco/learn/platform/Parcelable.jvm.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared/build.gradle.kts b/12-networking/projects/challenge/shared/build.gradle.kts index 0f43105d..9c5898e3 100644 --- a/12-networking/projects/challenge/shared/build.gradle.kts +++ b/12-networking/projects/challenge/shared/build.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,19 +32,18 @@ * THE SOFTWARE. */ -@file:Suppress("OPT_IN_USAGE") - +import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework plugins { alias(libs.plugins.android.library) alias(libs.plugins.jetbrains.kotlin.multiplatform) - alias(libs.plugins.jetbrains.kotlin.parcelize) alias(libs.plugins.jetbrains.kotlin.serialization) + alias(libs.plugins.jetbrains.kotlin.parcelize) alias(libs.plugins.cash.sqldelight) } -version = "2.0" +version = "3.0" sqldelight { databases { @@ -72,9 +71,21 @@ android { } kotlin { - androidTarget() + androidTarget { + compilerOptions { + // Issue #KT-58892: https://youtrack.jetbrains.com/issue/KT-58892/K2-Parcelize-doesnt-work-in-common-code-when-expect-annotation-is-actualized-with-typealias-to-Parcelize + freeCompilerArgs.addAll("-P", "plugin:org.jetbrains.kotlin.parcelize:additionalAnnotation=com.kodeco.learn.platform.Parcelize") + } + compilations.all { + compileTaskProvider.configure { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_17) + } + } + } + } - jvm("desktop") + jvm() val xcf = XCFramework("SharedKit") @@ -92,67 +103,57 @@ kotlin { } sourceSets { - targetHierarchy.default() + applyDefaultHierarchyTemplate() - getByName("commonMain") { - dependencies { - api(project(":shared-dto")) + commonMain.dependencies { + api(project(":shared-dto")) - implementation(libs.kotlinx.datetime) - implementation(libs.kotlinx.serialization.json) + implementation(libs.kotlinx.datetime) + implementation(libs.kotlinx.serialization.json) - implementation(libs.ktor.client.core) - implementation(libs.ktor.client.serialization) - implementation(libs.ktor.client.content.negotiation) - implementation(libs.ktor.client.logging) - implementation(libs.ktor.serialization.kotlinx.json) + implementation(libs.ktor.client.core) + implementation(libs.ktor.client.serialization) + implementation(libs.ktor.client.content.negotiation) + implementation(libs.ktor.serialization.kotlinx.json) + implementation(libs.ktor.client.logging) - implementation(libs.okio) - implementation(libs.korio) - } + implementation(libs.okio) + implementation(libs.korio) } - getByName("commonTest") { - dependencies { - implementation(kotlin("test-common")) - implementation(kotlin("test-annotations-common")) + commonTest.dependencies { + implementation(kotlin("test-common")) + implementation(kotlin("test-annotations-common")) - implementation(kotlin("test-junit")) - implementation(libs.junit) - implementation(libs.ktor.client.mock) - } + implementation(libs.ktor.client.mock) } - getByName("androidMain") { - dependencies { - implementation(libs.cash.sqldelight.android) + androidMain.dependencies { + implementation(libs.cash.sqldelight.android) - implementation(libs.ktor.client.android) - } + implementation(libs.ktor.client.android) } - getByName("androidUnitTest") { - dependencies { - implementation(kotlin("test-junit")) - } + androidUnitTest.dependencies { + implementation(kotlin("test-junit")) } - getByName("desktopMain") { - dependencies { - implementation(libs.cash.sqldelight.jvm) - } + jvmMain.dependencies { + implementation(libs.cash.sqldelight.jvm) } - getByName("iosMain") { - dependencies { - implementation(libs.cash.sqldelight.native) + iosMain.dependencies { + implementation(libs.cash.sqldelight.native) - implementation(libs.ktor.client.ios) - } + implementation(libs.ktor.client.ios) } } } -kotlin.sourceSets.all { - languageSettings.optIn("kotlin.RequiresOptIn") +kotlin.targets.configureEach { + compilations.configureEach { + compileTaskProvider.get().compilerOptions { + freeCompilerArgs.add("-Xexpect-actual-classes") + } + } } \ No newline at end of file diff --git a/12-networking/projects/challenge/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Database.android.kt b/12-networking/projects/challenge/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Database.android.kt index 9872f353..43fab8bb 100644 --- a/12-networking/projects/challenge/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Database.android.kt +++ b/12-networking/projects/challenge/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Database.android.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Identifier.android.kt b/12-networking/projects/challenge/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Identifier.android.kt index d38ebf8d..4de13720 100644 --- a/12-networking/projects/challenge/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Identifier.android.kt +++ b/12-networking/projects/challenge/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Identifier.android.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Logger.android.kt b/12-networking/projects/challenge/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Logger.android.kt index 5ffe7c44..e69c17d0 100644 --- a/12-networking/projects/challenge/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Logger.android.kt +++ b/12-networking/projects/challenge/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Logger.android.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Test.android.kt b/12-networking/projects/challenge/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Test.android.kt index 0d643309..39447147 100644 --- a/12-networking/projects/challenge/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Test.android.kt +++ b/12-networking/projects/challenge/shared/src/androidMain/kotlin/com/kodeco/learn/platform/Test.android.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/ServiceLocator.kt b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/ServiceLocator.kt index c1ebeb21..d36d288b 100644 --- a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/ServiceLocator.kt +++ b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/ServiceLocator.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/Values.kt b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/Values.kt index e12665e4..b5a9de54 100644 --- a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/Values.kt +++ b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/Values.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/data/FeedAPI.kt b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/data/FeedAPI.kt index 5e73c1df..e17b3b3e 100644 --- a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/data/FeedAPI.kt +++ b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/data/FeedAPI.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/data/HttpClientLogger.kt b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/data/HttpClientLogger.kt index 24f7ddc0..31ae32a9 100644 --- a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/data/HttpClientLogger.kt +++ b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/data/HttpClientLogger.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/domain/GetFeedData.kt b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/domain/GetFeedData.kt index fbd6f56e..9e2b325d 100644 --- a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/domain/GetFeedData.kt +++ b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/domain/GetFeedData.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/domain/cb/BookmarkData.kt b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/domain/cb/BookmarkData.kt index 41f3cee7..325cfde4 100644 --- a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/domain/cb/BookmarkData.kt +++ b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/domain/cb/BookmarkData.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/domain/cb/FeedData.kt b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/domain/cb/FeedData.kt index f8840287..02fc36dd 100644 --- a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/domain/cb/FeedData.kt +++ b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/domain/cb/FeedData.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/domain/dao/KodecoEntryDAO.kt b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/domain/dao/KodecoEntryDAO.kt index 00e083cb..4237edb2 100644 --- a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/domain/dao/KodecoEntryDAO.kt +++ b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/domain/dao/KodecoEntryDAO.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Database.common.kt b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Database.common.kt index 2900ec9d..d6561751 100644 --- a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Database.common.kt +++ b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Database.common.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Identifier.common.kt b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Identifier.common.kt index 54507367..8cb04425 100644 --- a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Identifier.common.kt +++ b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Identifier.common.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Logger.common.kt b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Logger.common.kt index a2fd9169..0315307a 100644 --- a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Logger.common.kt +++ b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Logger.common.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Test.common.kt b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Test.common.kt index a3df1ada..37fa556c 100644 --- a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Test.common.kt +++ b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/platform/Test.common.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/BookmarkPresenter.kt b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/BookmarkPresenter.kt index d57fa5e9..cdfec5a3 100644 --- a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/BookmarkPresenter.kt +++ b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/BookmarkPresenter.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/FeedPresenter.kt b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/FeedPresenter.kt index 5f4e9180..6e9ded11 100644 --- a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/FeedPresenter.kt +++ b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/FeedPresenter.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -36,6 +36,7 @@ package com.kodeco.learn.presentation import com.kodeco.learn.data.model.GravatarEntry import com.kodeco.learn.data.model.KodecoContent +import com.kodeco.learn.data.model.KodecoEntry import com.kodeco.learn.data.model.PLATFORM import com.kodeco.learn.domain.GetFeedData import com.kodeco.learn.domain.cb.FeedData @@ -58,6 +59,50 @@ private const val KODECO_CONTENT = "[" + "{\"platform\":\"growth\", \"url\":\"https://kodeco.com/professional-growth/feed\", \"image\":\"https://files.carolus.kodeco.com/gl22boss4ptciv7px3nnzcnct4ht?response_content_disposition=inline%3B+filename%3D%22progro.png%22%3B+filename%2A%3DUTF-8%27%27progro.png\"}" + "]" +private const val KODECO_ALL_FEED = """ + [ + { + "id": "https://www.kodeco.com/26244793-building-a-camera-app-with-swiftui-and-combine", + "link": "https://www.kodeco.com/26244793-building-a-camera-app-with-swiftui-and-combine", + "title": "Building a Camera App With SwiftUI and Combine [FREE]", + "summary":"Learn to natively build your own SwiftUI camera app using Combine and create fun filters using the power of Core Image.", + "updated": "2021-11-10T13:59:59Z" + }, + + { + "id": "https://www.kodeco.com/29045204-announcing-swiftui-by-tutorials-fourth-edition", + "link": "https://www.kodeco.com/29045204-announcing-swiftui-by-tutorials-fourth-edition", + "title": "Announcing SwiftUI by Tutorials, Fourth Edition! [FREE]", + "summary":"Build apps more efficiently with SwiftUI’s declarative approach and leave the old ways of imperative coding in the dust, with this freshly-updated book.", + "updated": "2021-11-10T13:44:43Z" + }, + + { + "id": "https://www.kodeco.com/books/swiftui-by-tutorialse", + "link": "https://www.kodeco.com/books/swiftui-by-tutorials", + "title": "SwiftUI by Tutorials [SUBSCRIBER]", + "summary":"Build fluid and engaging declarative UI for your apps — using less code — with SwiftUI!

SwiftUI by Tutorials is designed to help you learn how to transition from the “old way” of building your app UI with UIKit, to the “new way” of building responsive UI with modern declarative syntax with SwiftUI. This book is for readers who are comfortable building Swift apps, and want to make the exciting leap into building their app UI with modern, declarative code.

What is SwiftUI?

SwiftUI lets you build better apps, faster, and with less code. It’s a developer’s dream come true! With SwiftUI, you can design your user interfaces in a declarative way; instead of developing app interfaces in an imperative way, by coding all of the application state logic before time, you can instead define what your app’s UI should do in a particular state and let the underlying OS figure out how to do it. What’s more is that SwiftUI lets you build modern, responsive UI and animations for all Apple devices — not just iOS. So whether you’re building apps for iOS, watchOS, tvOS or any other Apple platform, you can use the same concise, natural language to describe your UI and have it look stunning — no matter where your code runs. In addition, SwiftUI’s built-in automatic support for things such as dark mode, localization and accessibility, along with Xcode 11 support for drag-and-drop design and instant preview makes it easier to build apps than ever before.

How is this book different than SwiftUI Apprentice?

Our other book on getting started with SwiftUI, SwiftUI Apprentice, is designed to teach new developers how to build iOS apps, using a SwiftUI-first approach. The goal of that book is to teach you fundamental development practices as you build out some fully-functional and great-looking apps! This book, SwiftUI by Tutorials, is designed for developers who have a solid background in iOS development, and are looking to make the leap from building apps with UIKit, to building apps with SwiftUI.", + "updated": "2021-11-10T00:00:00Z" + }, + + { + "id": "https://www.kodeco.com/26933987-flutter-ui-widgets", + "link": "https://www.kodeco.com/26933987-flutter-ui-widgets", + "title": "Flutter UI Widgets [SUBSCRIBER]", + "summary":"Explore commonly used UI widgets in Flutter and see how they relate to their native iOS and Android counterparts.", + "updated": "2021-11-09T00:00:00Z" + }, + + { + "id": "https://www.kodeco.com/26236685-shazamkit-tutorial-for-ios-getting-started", + "link": "https://www.kodeco.com/26236685-shazamkit-tutorial-for-ios-getting-started", + "title": "ShazamKit Tutorial for iOS: Getting Started [FREE]", + "summary":"Learn how to use ShazamKit to find information about specific audio recordings by matching a segment of that audio against a reference catalog of audio signatures.", + "updated": "2021-11-08T13:59:30Z" + } +] +""" + private const val GRAVATAR_EMAIL = "YOUR_GRAVATAR_EMAIL" class FeedPresenter(private val feed: GetFeedData) { @@ -68,6 +113,10 @@ class FeedPresenter(private val feed: GetFeedData) { json.decodeFromString(KODECO_CONTENT) } + val allFeeds: List by lazy { + json.decodeFromString(KODECO_ALL_FEED) + } + public fun fetchAllFeeds(cb: FeedData) { Logger.d(TAG, "fetchAllFeeds") @@ -93,7 +142,6 @@ class FeedPresenter(private val feed: GetFeedData) { } } - public fun fetchMyGravatar(cb: FeedData) { Logger.d(TAG, "fetchMyGravatar") diff --git a/12-networking/projects/challenge/shared/src/commonTest/kotlin/NetworkTests.kt b/12-networking/projects/challenge/shared/src/commonTest/kotlin/NetworkTests.kt index e15ff091..6564547b 100644 --- a/12-networking/projects/challenge/shared/src/commonTest/kotlin/NetworkTests.kt +++ b/12-networking/projects/challenge/shared/src/commonTest/kotlin/NetworkTests.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -47,8 +47,8 @@ import io.ktor.http.ContentType import io.ktor.http.HttpHeaders import io.ktor.http.headersOf import io.ktor.serialization.kotlinx.json.json -import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json +import kotlinx.serialization.encodeToString import kotlin.test.Test import kotlin.test.assertEquals diff --git a/12-networking/projects/challenge/shared/src/commonTest/kotlin/SerializationTests.kt b/12-networking/projects/challenge/shared/src/commonTest/kotlin/SerializationTests.kt index 5a2cfe8f..149a3135 100644 --- a/12-networking/projects/challenge/shared/src/commonTest/kotlin/SerializationTests.kt +++ b/12-networking/projects/challenge/shared/src/commonTest/kotlin/SerializationTests.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Database.ios.kt b/12-networking/projects/challenge/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Database.ios.kt index 1328413f..073d4cfd 100644 --- a/12-networking/projects/challenge/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Database.ios.kt +++ b/12-networking/projects/challenge/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Database.ios.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Identifier.ios.kt b/12-networking/projects/challenge/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Identifier.ios.kt index ba89d433..c6c13e98 100644 --- a/12-networking/projects/challenge/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Identifier.ios.kt +++ b/12-networking/projects/challenge/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Identifier.ios.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Logger.ios.kt b/12-networking/projects/challenge/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Logger.ios.kt index b8cb9781..4a0e1627 100644 --- a/12-networking/projects/challenge/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Logger.ios.kt +++ b/12-networking/projects/challenge/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Logger.ios.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Test.ios.kt b/12-networking/projects/challenge/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Test.ios.kt index 0d643309..39447147 100644 --- a/12-networking/projects/challenge/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Test.ios.kt +++ b/12-networking/projects/challenge/shared/src/iosMain/kotlin/com/kodeco/learn/platform/Test.ios.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Database.desktop.kt b/12-networking/projects/challenge/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Database.jvm.kt similarity index 98% rename from 12-networking/projects/challenge/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Database.desktop.kt rename to 12-networking/projects/challenge/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Database.jvm.kt index 2e55f0e1..83304e3a 100644 --- a/12-networking/projects/challenge/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Database.desktop.kt +++ b/12-networking/projects/challenge/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Database.jvm.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Identifier.desktop.kt b/12-networking/projects/challenge/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Identifier.jvm.kt similarity index 98% rename from 12-networking/projects/challenge/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Identifier.desktop.kt rename to 12-networking/projects/challenge/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Identifier.jvm.kt index 762c3b16..3e30206c 100644 --- a/12-networking/projects/challenge/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Identifier.desktop.kt +++ b/12-networking/projects/challenge/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Identifier.jvm.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Logger.desktop.kt b/12-networking/projects/challenge/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Logger.jvm.kt similarity index 98% rename from 12-networking/projects/challenge/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Logger.desktop.kt rename to 12-networking/projects/challenge/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Logger.jvm.kt index e77f3495..e68ad692 100644 --- a/12-networking/projects/challenge/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Logger.desktop.kt +++ b/12-networking/projects/challenge/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Logger.jvm.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/12-networking/projects/challenge/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Test.desktop.kt b/12-networking/projects/challenge/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Test.jvm.kt similarity index 98% rename from 12-networking/projects/challenge/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Test.desktop.kt rename to 12-networking/projects/challenge/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Test.jvm.kt index 0d643309..39447147 100644 --- a/12-networking/projects/challenge/shared/src/desktopMain/kotlin/com/kodeco/learn/platform/Test.desktop.kt +++ b/12-networking/projects/challenge/shared/src/jvmMain/kotlin/com/kodeco/learn/platform/Test.jvm.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Kodeco Inc + * Copyright (c) 2025 Kodeco Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal From 86ae41e7affe1abb8c671409e66f9d4929e8e8e2 Mon Sep 17 00:00:00 2001 From: Carlos Mota Date: Mon, 3 Feb 2025 04:25:32 +0000 Subject: [PATCH 5/6] Removed local feed Removed fetchLinkImage function from iOS app --- .../iosApp/iosApp/KodecoEntryViewModel.swift | 35 -------------- .../learn/presentation/FeedPresenter.kt | 48 ------------------- .../iosApp/iosApp/KodecoEntryViewModel.swift | 35 -------------- .../learn/presentation/FeedPresenter.kt | 48 ------------------- .../iosApp/iosApp/KodecoEntryViewModel.swift | 35 -------------- 5 files changed, 201 deletions(-) diff --git a/12-networking/projects/challenge/iosApp/iosApp/KodecoEntryViewModel.swift b/12-networking/projects/challenge/iosApp/iosApp/KodecoEntryViewModel.swift index 531e26e0..60b77ba1 100644 --- a/12-networking/projects/challenge/iosApp/iosApp/KodecoEntryViewModel.swift +++ b/12-networking/projects/challenge/iosApp/iosApp/KodecoEntryViewModel.swift @@ -71,41 +71,6 @@ class KodecoEntryViewModel: ObservableObject { } } - @MainActor - func fetchLinkImage() { - for platform in self.items.keys { - guard let items = self.items[platform] else { continue } - let subsetItems = Array(items[0 ..< Swift.min(self.fetchNImages, items.count)]) - for item in subsetItems { - FeedClient.shared.fetchLinkImage(item.platform, item.id, item.link) { id, url, platform in - guard let item = self.items[platform.description]?.first(where: { $0.id == id }) else { - return - } - - guard var list = self.items[platform.description] else { - return - } - guard let index = list.firstIndex(of: item) else { - return - } - - list[index] = item.doCopy( - id: item.id, - link: item.link, - title: item.title, - summary: item.summary, - updated: item.updated, - platform: item.platform, - imageUrl: url, - bookmarked: item.bookmarked - ) - - self.items[platform.description] = list - } - } - } - } - func fetchAllBookmarks() { BookmarkClient.shared.fetchBookmarks { items in Logger().d(tag: TAG, message: "fetchAllBookmarks: \(items.count) items") diff --git a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/FeedPresenter.kt b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/FeedPresenter.kt index 6e9ded11..cc83cc32 100644 --- a/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/FeedPresenter.kt +++ b/12-networking/projects/challenge/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/FeedPresenter.kt @@ -59,50 +59,6 @@ private const val KODECO_CONTENT = "[" + "{\"platform\":\"growth\", \"url\":\"https://kodeco.com/professional-growth/feed\", \"image\":\"https://files.carolus.kodeco.com/gl22boss4ptciv7px3nnzcnct4ht?response_content_disposition=inline%3B+filename%3D%22progro.png%22%3B+filename%2A%3DUTF-8%27%27progro.png\"}" + "]" -private const val KODECO_ALL_FEED = """ - [ - { - "id": "https://www.kodeco.com/26244793-building-a-camera-app-with-swiftui-and-combine", - "link": "https://www.kodeco.com/26244793-building-a-camera-app-with-swiftui-and-combine", - "title": "Building a Camera App With SwiftUI and Combine [FREE]", - "summary":"Learn to natively build your own SwiftUI camera app using Combine and create fun filters using the power of Core Image.", - "updated": "2021-11-10T13:59:59Z" - }, - - { - "id": "https://www.kodeco.com/29045204-announcing-swiftui-by-tutorials-fourth-edition", - "link": "https://www.kodeco.com/29045204-announcing-swiftui-by-tutorials-fourth-edition", - "title": "Announcing SwiftUI by Tutorials, Fourth Edition! [FREE]", - "summary":"Build apps more efficiently with SwiftUI’s declarative approach and leave the old ways of imperative coding in the dust, with this freshly-updated book.", - "updated": "2021-11-10T13:44:43Z" - }, - - { - "id": "https://www.kodeco.com/books/swiftui-by-tutorialse", - "link": "https://www.kodeco.com/books/swiftui-by-tutorials", - "title": "SwiftUI by Tutorials [SUBSCRIBER]", - "summary":"Build fluid and engaging declarative UI for your apps — using less code — with SwiftUI!

SwiftUI by Tutorials is designed to help you learn how to transition from the “old way” of building your app UI with UIKit, to the “new way” of building responsive UI with modern declarative syntax with SwiftUI. This book is for readers who are comfortable building Swift apps, and want to make the exciting leap into building their app UI with modern, declarative code.

What is SwiftUI?

SwiftUI lets you build better apps, faster, and with less code. It’s a developer’s dream come true! With SwiftUI, you can design your user interfaces in a declarative way; instead of developing app interfaces in an imperative way, by coding all of the application state logic before time, you can instead define what your app’s UI should do in a particular state and let the underlying OS figure out how to do it. What’s more is that SwiftUI lets you build modern, responsive UI and animations for all Apple devices — not just iOS. So whether you’re building apps for iOS, watchOS, tvOS or any other Apple platform, you can use the same concise, natural language to describe your UI and have it look stunning — no matter where your code runs. In addition, SwiftUI’s built-in automatic support for things such as dark mode, localization and accessibility, along with Xcode 11 support for drag-and-drop design and instant preview makes it easier to build apps than ever before.

How is this book different than SwiftUI Apprentice?

Our other book on getting started with SwiftUI, SwiftUI Apprentice, is designed to teach new developers how to build iOS apps, using a SwiftUI-first approach. The goal of that book is to teach you fundamental development practices as you build out some fully-functional and great-looking apps! This book, SwiftUI by Tutorials, is designed for developers who have a solid background in iOS development, and are looking to make the leap from building apps with UIKit, to building apps with SwiftUI.", - "updated": "2021-11-10T00:00:00Z" - }, - - { - "id": "https://www.kodeco.com/26933987-flutter-ui-widgets", - "link": "https://www.kodeco.com/26933987-flutter-ui-widgets", - "title": "Flutter UI Widgets [SUBSCRIBER]", - "summary":"Explore commonly used UI widgets in Flutter and see how they relate to their native iOS and Android counterparts.", - "updated": "2021-11-09T00:00:00Z" - }, - - { - "id": "https://www.kodeco.com/26236685-shazamkit-tutorial-for-ios-getting-started", - "link": "https://www.kodeco.com/26236685-shazamkit-tutorial-for-ios-getting-started", - "title": "ShazamKit Tutorial for iOS: Getting Started [FREE]", - "summary":"Learn how to use ShazamKit to find information about specific audio recordings by matching a segment of that audio against a reference catalog of audio signatures.", - "updated": "2021-11-08T13:59:30Z" - } -] -""" - private const val GRAVATAR_EMAIL = "YOUR_GRAVATAR_EMAIL" class FeedPresenter(private val feed: GetFeedData) { @@ -113,10 +69,6 @@ class FeedPresenter(private val feed: GetFeedData) { json.decodeFromString(KODECO_CONTENT) } - val allFeeds: List by lazy { - json.decodeFromString(KODECO_ALL_FEED) - } - public fun fetchAllFeeds(cb: FeedData) { Logger.d(TAG, "fetchAllFeeds") diff --git a/12-networking/projects/final/iosApp/iosApp/KodecoEntryViewModel.swift b/12-networking/projects/final/iosApp/iosApp/KodecoEntryViewModel.swift index 531e26e0..60b77ba1 100644 --- a/12-networking/projects/final/iosApp/iosApp/KodecoEntryViewModel.swift +++ b/12-networking/projects/final/iosApp/iosApp/KodecoEntryViewModel.swift @@ -71,41 +71,6 @@ class KodecoEntryViewModel: ObservableObject { } } - @MainActor - func fetchLinkImage() { - for platform in self.items.keys { - guard let items = self.items[platform] else { continue } - let subsetItems = Array(items[0 ..< Swift.min(self.fetchNImages, items.count)]) - for item in subsetItems { - FeedClient.shared.fetchLinkImage(item.platform, item.id, item.link) { id, url, platform in - guard let item = self.items[platform.description]?.first(where: { $0.id == id }) else { - return - } - - guard var list = self.items[platform.description] else { - return - } - guard let index = list.firstIndex(of: item) else { - return - } - - list[index] = item.doCopy( - id: item.id, - link: item.link, - title: item.title, - summary: item.summary, - updated: item.updated, - platform: item.platform, - imageUrl: url, - bookmarked: item.bookmarked - ) - - self.items[platform.description] = list - } - } - } - } - func fetchAllBookmarks() { BookmarkClient.shared.fetchBookmarks { items in Logger().d(tag: TAG, message: "fetchAllBookmarks: \(items.count) items") diff --git a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/FeedPresenter.kt b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/FeedPresenter.kt index 6e9ded11..cc83cc32 100644 --- a/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/FeedPresenter.kt +++ b/12-networking/projects/final/shared/src/commonMain/kotlin/com/kodeco/learn/presentation/FeedPresenter.kt @@ -59,50 +59,6 @@ private const val KODECO_CONTENT = "[" + "{\"platform\":\"growth\", \"url\":\"https://kodeco.com/professional-growth/feed\", \"image\":\"https://files.carolus.kodeco.com/gl22boss4ptciv7px3nnzcnct4ht?response_content_disposition=inline%3B+filename%3D%22progro.png%22%3B+filename%2A%3DUTF-8%27%27progro.png\"}" + "]" -private const val KODECO_ALL_FEED = """ - [ - { - "id": "https://www.kodeco.com/26244793-building-a-camera-app-with-swiftui-and-combine", - "link": "https://www.kodeco.com/26244793-building-a-camera-app-with-swiftui-and-combine", - "title": "Building a Camera App With SwiftUI and Combine [FREE]", - "summary":"Learn to natively build your own SwiftUI camera app using Combine and create fun filters using the power of Core Image.", - "updated": "2021-11-10T13:59:59Z" - }, - - { - "id": "https://www.kodeco.com/29045204-announcing-swiftui-by-tutorials-fourth-edition", - "link": "https://www.kodeco.com/29045204-announcing-swiftui-by-tutorials-fourth-edition", - "title": "Announcing SwiftUI by Tutorials, Fourth Edition! [FREE]", - "summary":"Build apps more efficiently with SwiftUI’s declarative approach and leave the old ways of imperative coding in the dust, with this freshly-updated book.", - "updated": "2021-11-10T13:44:43Z" - }, - - { - "id": "https://www.kodeco.com/books/swiftui-by-tutorialse", - "link": "https://www.kodeco.com/books/swiftui-by-tutorials", - "title": "SwiftUI by Tutorials [SUBSCRIBER]", - "summary":"Build fluid and engaging declarative UI for your apps — using less code — with SwiftUI!

SwiftUI by Tutorials is designed to help you learn how to transition from the “old way” of building your app UI with UIKit, to the “new way” of building responsive UI with modern declarative syntax with SwiftUI. This book is for readers who are comfortable building Swift apps, and want to make the exciting leap into building their app UI with modern, declarative code.

What is SwiftUI?

SwiftUI lets you build better apps, faster, and with less code. It’s a developer’s dream come true! With SwiftUI, you can design your user interfaces in a declarative way; instead of developing app interfaces in an imperative way, by coding all of the application state logic before time, you can instead define what your app’s UI should do in a particular state and let the underlying OS figure out how to do it. What’s more is that SwiftUI lets you build modern, responsive UI and animations for all Apple devices — not just iOS. So whether you’re building apps for iOS, watchOS, tvOS or any other Apple platform, you can use the same concise, natural language to describe your UI and have it look stunning — no matter where your code runs. In addition, SwiftUI’s built-in automatic support for things such as dark mode, localization and accessibility, along with Xcode 11 support for drag-and-drop design and instant preview makes it easier to build apps than ever before.

How is this book different than SwiftUI Apprentice?

Our other book on getting started with SwiftUI, SwiftUI Apprentice, is designed to teach new developers how to build iOS apps, using a SwiftUI-first approach. The goal of that book is to teach you fundamental development practices as you build out some fully-functional and great-looking apps! This book, SwiftUI by Tutorials, is designed for developers who have a solid background in iOS development, and are looking to make the leap from building apps with UIKit, to building apps with SwiftUI.", - "updated": "2021-11-10T00:00:00Z" - }, - - { - "id": "https://www.kodeco.com/26933987-flutter-ui-widgets", - "link": "https://www.kodeco.com/26933987-flutter-ui-widgets", - "title": "Flutter UI Widgets [SUBSCRIBER]", - "summary":"Explore commonly used UI widgets in Flutter and see how they relate to their native iOS and Android counterparts.", - "updated": "2021-11-09T00:00:00Z" - }, - - { - "id": "https://www.kodeco.com/26236685-shazamkit-tutorial-for-ios-getting-started", - "link": "https://www.kodeco.com/26236685-shazamkit-tutorial-for-ios-getting-started", - "title": "ShazamKit Tutorial for iOS: Getting Started [FREE]", - "summary":"Learn how to use ShazamKit to find information about specific audio recordings by matching a segment of that audio against a reference catalog of audio signatures.", - "updated": "2021-11-08T13:59:30Z" - } -] -""" - private const val GRAVATAR_EMAIL = "YOUR_GRAVATAR_EMAIL" class FeedPresenter(private val feed: GetFeedData) { @@ -113,10 +69,6 @@ class FeedPresenter(private val feed: GetFeedData) { json.decodeFromString(KODECO_CONTENT) } - val allFeeds: List by lazy { - json.decodeFromString(KODECO_ALL_FEED) - } - public fun fetchAllFeeds(cb: FeedData) { Logger.d(TAG, "fetchAllFeeds") diff --git a/12-networking/projects/starter/iosApp/iosApp/KodecoEntryViewModel.swift b/12-networking/projects/starter/iosApp/iosApp/KodecoEntryViewModel.swift index 531e26e0..60b77ba1 100644 --- a/12-networking/projects/starter/iosApp/iosApp/KodecoEntryViewModel.swift +++ b/12-networking/projects/starter/iosApp/iosApp/KodecoEntryViewModel.swift @@ -71,41 +71,6 @@ class KodecoEntryViewModel: ObservableObject { } } - @MainActor - func fetchLinkImage() { - for platform in self.items.keys { - guard let items = self.items[platform] else { continue } - let subsetItems = Array(items[0 ..< Swift.min(self.fetchNImages, items.count)]) - for item in subsetItems { - FeedClient.shared.fetchLinkImage(item.platform, item.id, item.link) { id, url, platform in - guard let item = self.items[platform.description]?.first(where: { $0.id == id }) else { - return - } - - guard var list = self.items[platform.description] else { - return - } - guard let index = list.firstIndex(of: item) else { - return - } - - list[index] = item.doCopy( - id: item.id, - link: item.link, - title: item.title, - summary: item.summary, - updated: item.updated, - platform: item.platform, - imageUrl: url, - bookmarked: item.bookmarked - ) - - self.items[platform.description] = list - } - } - } - } - func fetchAllBookmarks() { BookmarkClient.shared.fetchBookmarks { items in Logger().d(tag: TAG, message: "fetchAllBookmarks: \(items.count) items") From 35741388f50219a60e6097721d790640b5a866ac Mon Sep 17 00:00:00 2001 From: Carlos Mota Date: Sun, 9 Feb 2025 03:00:13 +0000 Subject: [PATCH 6/6] - Limited items to 5 in LatestContent. - Updated bottom sheet state in MainScreen. --- .../main/java/com/kodeco/learn/ui/latest/LatestContent.kt | 4 +++- .../src/main/java/com/kodeco/learn/ui/main/MainScreen.kt | 5 ++++- .../kotlin/com/kodeco/learn/ui/latest/LatestContent.kt | 4 +++- .../main/java/com/kodeco/learn/ui/latest/LatestContent.kt | 4 +++- .../src/main/java/com/kodeco/learn/ui/main/MainScreen.kt | 5 ++++- .../kotlin/com/kodeco/learn/ui/latest/LatestContent.kt | 4 +++- .../main/java/com/kodeco/learn/ui/latest/LatestContent.kt | 4 +++- .../src/main/java/com/kodeco/learn/ui/main/MainScreen.kt | 5 ++++- 8 files changed, 27 insertions(+), 8 deletions(-) diff --git a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/latest/LatestContent.kt b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/latest/LatestContent.kt index 382e52a5..4c0f0096 100644 --- a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/latest/LatestContent.kt +++ b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/latest/LatestContent.kt @@ -73,6 +73,8 @@ import com.kodeco.learn.ui.theme.colorContent85Transparency private const val TAG = "LatestContent" +private const val ITEMS = 5 + @Composable fun LatestContent( items: SnapshotStateMap>, @@ -109,7 +111,7 @@ fun AddPages( AddNewPage( platform = platform, - items = items[platform] ?: emptyList(), + items = items[platform]?.subList(0, ITEMS) ?: emptyList(), onOpenEntry = onOpenEntry ) } diff --git a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/main/MainScreen.kt b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/main/MainScreen.kt index 4f17901a..52d7037c 100644 --- a/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/main/MainScreen.kt +++ b/12-networking/projects/challenge/androidApp/src/main/java/com/kodeco/learn/ui/main/MainScreen.kt @@ -41,6 +41,7 @@ import androidx.compose.material3.BottomSheetScaffold import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.rememberBottomSheetScaffoldState import androidx.compose.material3.Scaffold +import androidx.compose.material3.rememberStandardBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.State @@ -80,7 +81,9 @@ fun MainScreen( navController.enableOnBackPressed(false) val coroutineScope = rememberCoroutineScope() - val bottomSheetScaffoldState = rememberBottomSheetScaffoldState() + val bottomSheetScaffoldState = rememberBottomSheetScaffoldState( + bottomSheetState = rememberStandardBottomSheetState(skipHiddenState = false) + ) selected = remember { mutableStateOf(KodecoEntry()) } diff --git a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/latest/LatestContent.kt b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/latest/LatestContent.kt index f88cd468..67274da2 100644 --- a/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/latest/LatestContent.kt +++ b/12-networking/projects/challenge/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/latest/LatestContent.kt @@ -71,6 +71,8 @@ import com.kodeco.learn.ui.theme.colorContent85Transparency private const val TAG = "LatestContent" +private const val ITEMS = 5 + @Composable fun LatestContent( items: SnapshotStateMap>, @@ -107,7 +109,7 @@ fun AddPages( AddNewPage( platform = platform, - items = items[platform] ?: emptyList(), + items = items[platform]?.subList(0, ITEMS) ?: emptyList(), onOpenEntry = onOpenEntry ) } diff --git a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/latest/LatestContent.kt b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/latest/LatestContent.kt index 382e52a5..4c0f0096 100644 --- a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/latest/LatestContent.kt +++ b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/latest/LatestContent.kt @@ -73,6 +73,8 @@ import com.kodeco.learn.ui.theme.colorContent85Transparency private const val TAG = "LatestContent" +private const val ITEMS = 5 + @Composable fun LatestContent( items: SnapshotStateMap>, @@ -109,7 +111,7 @@ fun AddPages( AddNewPage( platform = platform, - items = items[platform] ?: emptyList(), + items = items[platform]?.subList(0, ITEMS) ?: emptyList(), onOpenEntry = onOpenEntry ) } diff --git a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/main/MainScreen.kt b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/main/MainScreen.kt index 4f17901a..52d7037c 100644 --- a/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/main/MainScreen.kt +++ b/12-networking/projects/final/androidApp/src/main/java/com/kodeco/learn/ui/main/MainScreen.kt @@ -41,6 +41,7 @@ import androidx.compose.material3.BottomSheetScaffold import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.rememberBottomSheetScaffoldState import androidx.compose.material3.Scaffold +import androidx.compose.material3.rememberStandardBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.State @@ -80,7 +81,9 @@ fun MainScreen( navController.enableOnBackPressed(false) val coroutineScope = rememberCoroutineScope() - val bottomSheetScaffoldState = rememberBottomSheetScaffoldState() + val bottomSheetScaffoldState = rememberBottomSheetScaffoldState( + bottomSheetState = rememberStandardBottomSheetState(skipHiddenState = false) + ) selected = remember { mutableStateOf(KodecoEntry()) } diff --git a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/latest/LatestContent.kt b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/latest/LatestContent.kt index f88cd468..67274da2 100644 --- a/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/latest/LatestContent.kt +++ b/12-networking/projects/final/desktopApp/src/jvmMain/kotlin/com/kodeco/learn/ui/latest/LatestContent.kt @@ -71,6 +71,8 @@ import com.kodeco.learn.ui.theme.colorContent85Transparency private const val TAG = "LatestContent" +private const val ITEMS = 5 + @Composable fun LatestContent( items: SnapshotStateMap>, @@ -107,7 +109,7 @@ fun AddPages( AddNewPage( platform = platform, - items = items[platform] ?: emptyList(), + items = items[platform]?.subList(0, ITEMS) ?: emptyList(), onOpenEntry = onOpenEntry ) } diff --git a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/latest/LatestContent.kt b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/latest/LatestContent.kt index 382e52a5..4c0f0096 100644 --- a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/latest/LatestContent.kt +++ b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/latest/LatestContent.kt @@ -73,6 +73,8 @@ import com.kodeco.learn.ui.theme.colorContent85Transparency private const val TAG = "LatestContent" +private const val ITEMS = 5 + @Composable fun LatestContent( items: SnapshotStateMap>, @@ -109,7 +111,7 @@ fun AddPages( AddNewPage( platform = platform, - items = items[platform] ?: emptyList(), + items = items[platform]?.subList(0, ITEMS) ?: emptyList(), onOpenEntry = onOpenEntry ) } diff --git a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/main/MainScreen.kt b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/main/MainScreen.kt index 4f17901a..52d7037c 100644 --- a/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/main/MainScreen.kt +++ b/12-networking/projects/starter/androidApp/src/main/java/com/kodeco/learn/ui/main/MainScreen.kt @@ -41,6 +41,7 @@ import androidx.compose.material3.BottomSheetScaffold import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.rememberBottomSheetScaffoldState import androidx.compose.material3.Scaffold +import androidx.compose.material3.rememberStandardBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.State @@ -80,7 +81,9 @@ fun MainScreen( navController.enableOnBackPressed(false) val coroutineScope = rememberCoroutineScope() - val bottomSheetScaffoldState = rememberBottomSheetScaffoldState() + val bottomSheetScaffoldState = rememberBottomSheetScaffoldState( + bottomSheetState = rememberStandardBottomSheetState(skipHiddenState = false) + ) selected = remember { mutableStateOf(KodecoEntry()) }