Skip to content

Commit

Permalink
Merge pull request #15 from Taewan-P/feat/about-page
Browse files Browse the repository at this point in the history
Add about page & license page
  • Loading branch information
Taewan-P authored Jul 5, 2024
2 parents 7b6e04a + 1f65aae commit 893f4bb
Show file tree
Hide file tree
Showing 18 changed files with 387 additions and 13 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,6 @@ Cross platform updates are supported. However, GitHub Releases will be the faste
## License

See [LICENSE](./LICENSE) for details.

[F-Droid Icon License](https://gitlab.com/fdroid/artwork/-/blob/master/fdroid-logo-2015/README.md)

9 changes: 7 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ plugins {
alias(libs.plugins.android.hilt)
alias(libs.plugins.kotlin.ksp)
alias(libs.plugins.kotlin.parcelize)
alias(libs.plugins.auto.license)
kotlin(libs.plugins.kotlin.serialization.get().pluginId).version(libs.versions.kotlin)
}

Expand All @@ -15,8 +16,8 @@ android {
applicationId = "dev.chungjungsoo.gptmobile"
minSdk = 28
targetSdk = 34
versionCode = 5
versionName = "0.3.2"
versionCode = 6
versionName = "0.4.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
Expand Down Expand Up @@ -93,6 +94,10 @@ dependencies {
implementation(libs.ktor.logging)
implementation(libs.ktor.serialization)

// License page UI
implementation(libs.auto.license.core)
implementation(libs.auto.license.ui)

// Markdown
implementation(libs.compose.markdown)
implementation(libs.richtext)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class SettingRepositoryImpl @Inject constructor(
}

if (platform.systemPrompt != null) {
settingDataSource.updateSystemPrompt(platform.name, platform.systemPrompt)
settingDataSource.updateSystemPrompt(platform.name, platform.systemPrompt.trim())
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import androidx.navigation.navigation
import dev.chungjungsoo.gptmobile.data.model.ApiType
import dev.chungjungsoo.gptmobile.presentation.ui.chat.ChatScreen
import dev.chungjungsoo.gptmobile.presentation.ui.home.HomeScreen
import dev.chungjungsoo.gptmobile.presentation.ui.setting.AboutScreen
import dev.chungjungsoo.gptmobile.presentation.ui.setting.LicenseScreen
import dev.chungjungsoo.gptmobile.presentation.ui.setting.PlatformSettingScreen
import dev.chungjungsoo.gptmobile.presentation.ui.setting.SettingScreen
import dev.chungjungsoo.gptmobile.presentation.ui.setting.SettingViewModel
Expand Down Expand Up @@ -181,13 +183,14 @@ fun NavGraphBuilder.settingNavigation(navController: NavHostController) {
SettingScreen(
settingViewModel = settingViewModel,
onNavigationClick = { navController.navigateUp() },
onNavigate = { apiType ->
onNavigateToPlatformSetting = { apiType ->
when (apiType) {
ApiType.OPENAI -> navController.navigate(Route.OPENAI_SETTINGS)
ApiType.ANTHROPIC -> navController.navigate(Route.ANTHROPIC_SETTINGS)
ApiType.GOOGLE -> navController.navigate(Route.GOOGLE_SETTINGS)
}
}
},
onNavigateToAboutPage = { navController.navigate(Route.ABOUT_PAGE) }
)
}
composable(Route.OPENAI_SETTINGS) {
Expand Down Expand Up @@ -220,5 +223,14 @@ fun NavGraphBuilder.settingNavigation(navController: NavHostController) {
apiType = ApiType.GOOGLE
) { navController.navigateUp() }
}
composable(Route.ABOUT_PAGE) {
AboutScreen(
onNavigationClick = { navController.navigateUp() },
onNavigationToLicense = { navController.navigate(Route.LICENSE) }
)
}
composable(Route.LICENSE) {
LicenseScreen(onNavigationClick = { navController.navigateUp() })
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ object Route {
const val ANTHROPIC_SETTINGS = "anthropic_settings"
const val GOOGLE_SETTINGS = "google_settings"
const val ABOUT_PAGE = "about"
const val LICENSE = "license"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
package dev.chungjungsoo.gptmobile.presentation.ui.setting

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LargeTopAppBar
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import dev.chungjungsoo.gptmobile.R
import dev.chungjungsoo.gptmobile.presentation.common.SettingItem

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AboutScreen(
onNavigationClick: () -> Unit,
onNavigationToLicense: () -> Unit
) {
val scrollState = rememberScrollState()
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
val context = LocalContext.current
val version = context.packageManager.getPackageInfo(context.packageName, 0).versionName
val clipboardManager = LocalClipboardManager.current
val uriHandler = LocalUriHandler.current
val githubLink = stringResource(R.string.github_link)
val fdroidLink = stringResource(R.string.f_droid_link)
val googlePlayLink = stringResource(R.string.play_store_link)
val feedbackLink = stringResource(R.string.feedback_link)

Scaffold(
modifier = Modifier
.nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = {
AboutTopAppBar(
scrollBehavior = scrollBehavior,
navigationOnClick = onNavigationClick
)
}
) { innerPadding ->
Column(
modifier = Modifier
.padding(innerPadding)
.verticalScroll(scrollState)
) {
SettingItem(
modifier = Modifier.height(64.dp),
title = stringResource(R.string.version),
description = "v$version",
onItemClick = { clipboardManager.setText(AnnotatedString("v$version")) },
showTrailingIcon = false,
showLeadingIcon = true,
leadingIcon = {
Icon(
ImageVector.vectorResource(id = R.drawable.ic_info),
contentDescription = stringResource(R.string.version_icon)
)
}
)
SettingItem(
modifier = Modifier.height(64.dp),
title = stringResource(R.string.license),
description = stringResource(R.string.license_description),
onItemClick = onNavigationToLicense,
showTrailingIcon = true,
showLeadingIcon = true,
leadingIcon = {
Icon(
ImageVector.vectorResource(id = R.drawable.ic_license),
contentDescription = stringResource(R.string.license_icon)
)
}
)
SettingItem(
modifier = Modifier.height(64.dp),
title = stringResource(R.string.github),
onItemClick = { uriHandler.openUri(githubLink) },
showTrailingIcon = false,
showLeadingIcon = true,
leadingIcon = {
Icon(
ImageVector.vectorResource(id = R.drawable.ic_github),
contentDescription = stringResource(R.string.github_icon)
)
}
)
SettingItem(
modifier = Modifier.height(64.dp),
title = stringResource(R.string.f_droid),
onItemClick = { uriHandler.openUri(fdroidLink) },
showTrailingIcon = false,
showLeadingIcon = true,
leadingIcon = {
Icon(
ImageVector.vectorResource(id = R.drawable.ic_f_droid),
contentDescription = stringResource(R.string.f_droid_icon)
)
}
)
SettingItem(
modifier = Modifier.height(64.dp),
title = stringResource(R.string.play_store),
onItemClick = { uriHandler.openUri(googlePlayLink) },
showTrailingIcon = false,
showLeadingIcon = true,
leadingIcon = {
Icon(
ImageVector.vectorResource(id = R.drawable.ic_play_store),
contentDescription = stringResource(R.string.play_store_icon)
)
}
)
SettingItem(
modifier = Modifier.height(64.dp),
title = stringResource(R.string.feedback),
description = stringResource(R.string.feedback_description),
onItemClick = { uriHandler.openUri(feedbackLink) },
showTrailingIcon = false,
showLeadingIcon = true,
leadingIcon = {
Icon(
ImageVector.vectorResource(id = R.drawable.ic_feedback),
contentDescription = stringResource(R.string.feedback_icon)
)
}
)
}
}
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AboutTopAppBar(
scrollBehavior: TopAppBarScrollBehavior,
navigationOnClick: () -> Unit
) {
LargeTopAppBar(
colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.background,
titleContentColor = MaterialTheme.colorScheme.onBackground
),
title = {
Text(
modifier = Modifier.padding(4.dp),
text = stringResource(R.string.about),
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
},
navigationIcon = {
IconButton(
modifier = Modifier.padding(4.dp),
onClick = navigationOnClick
) {
Icon(imageVector = Icons.AutoMirrored.Filled.ArrowBack, contentDescription = stringResource(R.string.go_back))
}
},
scrollBehavior = scrollBehavior
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package dev.chungjungsoo.gptmobile.presentation.ui.setting

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LargeTopAppBar
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.mikepenz.aboutlibraries.ui.compose.m3.LibrariesContainer
import dev.chungjungsoo.gptmobile.R

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun LicenseScreen(
onNavigationClick: () -> Unit
) {
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()

Scaffold(
modifier = Modifier
.nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = {
LicenseTopAppBar(onNavigationClick, scrollBehavior)
}
) { innerPadding ->
Column(
modifier = Modifier.padding(innerPadding)
) {
LibrariesContainer(modifier = Modifier.fillMaxSize())
}
}
}

@Composable
@OptIn(ExperimentalMaterial3Api::class)
private fun LicenseTopAppBar(
onNavigationClick: () -> Unit,
scrollBehavior: TopAppBarScrollBehavior
) {
LargeTopAppBar(
colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.background,
titleContentColor = MaterialTheme.colorScheme.onBackground
),
title = {
Text(
modifier = Modifier.padding(4.dp),
text = stringResource(R.string.license),
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
},
navigationIcon = {
IconButton(
modifier = Modifier.padding(4.dp),
onClick = onNavigationClick
) {
Icon(imageVector = Icons.AutoMirrored.Filled.ArrowBack, contentDescription = stringResource(R.string.go_back))
}
},
scrollBehavior = scrollBehavior
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ fun SettingScreen(
modifier: Modifier = Modifier,
settingViewModel: SettingViewModel = hiltViewModel(),
onNavigationClick: () -> Unit,
onNavigate: (ApiType) -> Unit
onNavigateToPlatformSetting: (ApiType) -> Unit,
onNavigateToAboutPage: () -> Unit
) {
val scrollState = rememberScrollState()
val scrollBehavior = pinnedExitUntilCollapsedScrollBehavior(
Expand Down Expand Up @@ -78,11 +79,12 @@ fun SettingScreen(
SettingItem(
title = getPlatformSettingTitle(apiType),
description = getPlatformSettingDescription(apiType),
onItemClick = { onNavigate(apiType) },
onItemClick = { onNavigateToPlatformSetting(apiType) },
showTrailingIcon = true,
showLeadingIcon = false
)
}
AboutPageItem(onItemClick = onNavigateToAboutPage)

if (dialogState.isThemeDialogOpen) {
ThemeSettingDialog(settingViewModel)
Expand Down Expand Up @@ -135,6 +137,19 @@ fun ThemeSetting(
)
}

@Composable
fun AboutPageItem(
onItemClick: () -> Unit
) {
SettingItem(
title = stringResource(R.string.about),
description = stringResource(R.string.about_description),
onItemClick = onItemClick,
showTrailingIcon = true,
showLeadingIcon = false
)
}

@Composable
fun ThemeSettingDialog(
settingViewModel: SettingViewModel = hiltViewModel()
Expand Down
Loading

0 comments on commit 893f4bb

Please sign in to comment.