Added additional info dialog

This commit is contained in:
Abdelilah El Aissaoui 2022-04-04 18:32:06 +02:00
parent d85574fe6a
commit 27e8efcaf7
7 changed files with 210 additions and 24 deletions

View file

@ -34,7 +34,7 @@ dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2")
kapt("com.google.dagger:dagger-compiler:2.41")
testImplementation(platform("org.junit:junit-bom:5.8.2"))
testImplementation("org.junit.jupiter:junit-jupiter")
testImplementation("org.junit.jupiter:junit-jupiter:5.8.2")
testImplementation("io.mockk:mockk:1.12.3")
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-scalars:2.9.0")

View file

@ -1,8 +1,30 @@
package app
object AppConstants {
val openSourceProjects = listOf(
Project("Apache SSHD", "https://mina.apache.org/sshd-project/", apache__2_0),
Project("Google/Dagger", "https://dagger.dev/", apache__2_0),
Project("Jetbrains Compose", "https://www.jetbrains.com/lp/compose-mpp/", apache__2_0),
Project("JGit", "https://www.eclipse.org/jgit/", edl),
Project("JUnit 5", "https://junit.org/junit5/", edl),
Project("Kotlin", "https://kotlinlang.org/", apache__2_0),
Project("Kotlinx.serialization", "https://kotlinlang.org/docs/serialization.html#example-json-serialization", apache__2_0),
Project("Mockk", "https://mockk.io/", apache__2_0),
Project("Retrofit2", "https://square.github.io/retrofit/", apache__2_0),
)
// Remember to update build.gradle when changing this
const val APP_NAME = "Gitnuro"
const val APP_DESCRIPTION = "Gitnuro is a Git client that allows you to manage multiple repositories with a modern experience and live visual representation of your repository's state."
const val APP_VERSION = "0.1.0"
const val APP_VERSION_CODE = 1
const val VERSION_CHECK_URL = "https://raw.githubusercontent.com/JetpackDuba/Gitnuro/main/latest.json"
}
}
private val apache__2_0 = License("Apache 2.0", "https://www.apache.org/licenses/LICENSE-2.0")
private val edl = License("EDL", "https://www.eclipse.org/org/documents/edl-v10.php")
data class License(val name: String, val url: String)
data class Project(val name: String, val url: String, val license: License)

View file

@ -1,7 +1,13 @@
package app.extensions
import java.awt.Desktop
import java.net.URI
import java.nio.file.FileSystems
val systemSeparator: String by lazy {
FileSystems.getDefault().separator
}
fun openUrlInBrowser(url: String) {
Desktop.getDesktop().browse(URI(url))
}

View file

@ -23,15 +23,15 @@ import app.AppConstants
import app.AppStateManager
import app.extensions.dirName
import app.extensions.dirPath
import app.extensions.openUrlInBrowser
import app.theme.primaryTextColor
import app.theme.secondaryTextColor
import app.ui.dialogs.AppInfoDialog
import app.ui.dialogs.CloneDialog
import app.updates.Update
import app.viewmodels.TabViewModel
import openDirectoryDialog
import openRepositoryDialog
import java.awt.Desktop
import java.net.URI
@OptIn(ExperimentalMaterialApi::class)
@ -41,12 +41,13 @@ fun WelcomePage(
) {
val appStateManager = tabViewModel.appStateManager
var showCloneView by remember { mutableStateOf(false) }
var showAdditionalInfo by remember { mutableStateOf(false) }
var newUpdate by remember { mutableStateOf<Update?>(null) }
LaunchedEffect(Unit) {
val latestRelease = tabViewModel.latestRelease()
if(latestRelease != null && latestRelease.appCode > AppConstants.APP_VERSION_CODE) {
if (latestRelease != null && latestRelease.appCode > AppConstants.APP_VERSION_CODE) {
newUpdate = latestRelease
}
}
@ -64,9 +65,8 @@ fun WelcomePage(
HomeButtons(
newUpdate = newUpdate,
tabViewModel = tabViewModel,
onShowCloneView = {
showCloneView = true
}
onShowCloneView = { showCloneView = true },
onShowAdditionalInfo = { showAdditionalInfo = true },
)
RecentRepositories(appStateManager, tabViewModel)
@ -83,20 +83,29 @@ fun WelcomePage(
}
LaunchedEffect(showCloneView) {
if (showCloneView) tabViewModel.cloneViewModel.reset() // Reset dialog before showing it
if (showCloneView) {
tabViewModel.cloneViewModel.reset() // Reset dialog before showing it
}
}
if (showCloneView) {
CloneDialog(
tabViewModel.cloneViewModel,
onClose = {
showCloneView = false
tabViewModel.cloneViewModel.reset()
},
onOpenRepository = { dir ->
tabViewModel.openRepository(dir)
},
)
}
if (showCloneView) CloneDialog(
tabViewModel.cloneViewModel,
onClose = {
showCloneView = false
tabViewModel.cloneViewModel.reset()
},
onOpenRepository = { dir ->
tabViewModel.openRepository(dir)
},
)
if (showAdditionalInfo) {
AppInfoDialog(
onClose = { showAdditionalInfo = false },
)
}
}
@Composable
@ -104,6 +113,7 @@ fun HomeButtons(
newUpdate: Update?,
tabViewModel: TabViewModel,
onShowCloneView: () -> Unit,
onShowAdditionalInfo: () -> Unit,
) {
Column(
modifier = Modifier.padding(end = 32.dp),
@ -149,7 +159,7 @@ fun HomeButtons(
title = "Source code",
painter = painterResource("code.svg"),
onClick = {
Desktop.getDesktop().browse(URI("https://github.com/JetpackDuba/Gitnuro"))
openUrlInBrowser("https://github.com/JetpackDuba/Gitnuro")
}
)
@ -157,17 +167,23 @@ fun HomeButtons(
title = "Report a bug",
painter = painterResource("bug.svg"),
onClick = {
Desktop.getDesktop().browse(URI("https://github.com/JetpackDuba/Gitnuro/issues"))
openUrlInBrowser("https://github.com/JetpackDuba/Gitnuro/issues")
}
)
if(newUpdate != null) {
IconTextButton(
title = "Additional information",
painter = painterResource("info.svg"),
onClick = onShowAdditionalInfo
)
if (newUpdate != null) {
IconTextButton(
title = "New update ${newUpdate.appVersion} available ",
painter = painterResource("grade.svg"),
iconColor = MaterialTheme.colors.secondary,
onClick = {
Desktop.getDesktop().browse(URI(newUpdate.downloadUrl))
openUrlInBrowser(newUpdate.downloadUrl)
}
)
}
@ -188,7 +204,7 @@ fun RecentRepositories(appStateManager: AppStateManager, tabViewModel: TabViewMo
color = MaterialTheme.colors.primaryTextColor,
)
if(latestOpenedRepositoriesPaths.isEmpty()) {
if (latestOpenedRepositoriesPaths.isEmpty()) {
Text(
"Nothing to see here, open a repository first!",
color = MaterialTheme.colors.secondaryTextColor,

View file

@ -0,0 +1,42 @@
package app.ui.components
import androidx.compose.foundation.clickable
import androidx.compose.foundation.hoverable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsHoveredAsState
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import app.extensions.openUrlInBrowser
import app.theme.primaryTextColor
@Composable
fun TextLink(
text: String,
url: String,
modifier: Modifier = Modifier,
colorsInverted: Boolean = false,
) {
val hoverInteraction = remember { MutableInteractionSource() }
val isHovered by hoverInteraction.collectIsHoveredAsState()
val textColor = if (isHovered == colorsInverted) {
MaterialTheme.colors.primaryTextColor
} else {
MaterialTheme.colors.primary
}
Text(
text = text,
modifier = Modifier
.hoverable(hoverInteraction)
.clickable {
openUrlInBrowser(url)
}
.then(modifier),
color = textColor,
)
}

View file

@ -0,0 +1,99 @@
package app.ui.dialogs
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.items
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import app.AppConstants
import app.AppConstants.openSourceProjects
import app.Project
import app.theme.primaryTextColor
import app.ui.components.ScrollableLazyColumn
import app.ui.components.TextLink
@Composable
fun AppInfoDialog(
onClose: () -> Unit,
) {
MaterialDialog {
Column(
modifier = Modifier
.width(600.dp)
.height(600.dp)
) {
ScrollableLazyColumn(
modifier = Modifier
.weight(1f)
) {
item {
Column(modifier = Modifier.padding(16.dp)) {
Text(
AppConstants.APP_NAME,
fontSize = 24.sp,
color = MaterialTheme.colors.primaryTextColor,
)
Text(
AppConstants.APP_DESCRIPTION,
fontSize = 14.sp,
color = MaterialTheme.colors.primaryTextColor,
modifier = Modifier.padding(top = 16.dp)
)
Text(
"Gitnuro has been possible thanks to the following open source projects:",
fontSize = 14.sp,
color = MaterialTheme.colors.primaryTextColor,
modifier = Modifier.padding(vertical = 16.dp)
)
}
}
items(openSourceProjects) {
ProjectUsed(it)
}
}
TextButton(
modifier = Modifier
.padding(top = 16.dp, end = 8.dp)
.align(Alignment.End),
onClick = onClose
) {
Text("Close")
}
}
}
}
@Composable
fun ProjectUsed(project: Project) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.padding(horizontal = 16.dp)
) {
TextLink(
text = project.name,
url = project.url,
modifier = Modifier
.padding(vertical = 8.dp)
)
Spacer(Modifier.weight(1f))
TextLink(
text = project.license.name,
url = project.license.url,
modifier = Modifier
.padding(vertical = 8.dp),
colorsInverted = true
)
}
}

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/></svg>

After

Width:  |  Height:  |  Size: 253 B