Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/src/main/java/io/github/wiiznokes/gitnote/MyApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch

const val TAG = "MyApp (Application)"

class MyApp : Application() {

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import android.Manifest
import android.content.Context
import android.os.Build
import androidx.core.content.PermissionChecker
import java.net.InetAddress
import java.net.URI
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.net.InetAddress
import java.net.URI

class NetworkPermissionHelper {
companion object {
Expand All @@ -19,30 +19,31 @@ class NetworkPermissionHelper {
) == PermissionChecker.PERMISSION_GRANTED
}

suspend fun requiresLocalNetworkPermission(urlString: String): Boolean = withContext(Dispatchers.IO) {
try {
val host = if (urlString.contains("://")) {
URI(urlString).host
} else {
val afterAt = urlString.substringAfter('@', urlString)
afterAt.substringBefore(':')
}
suspend fun requiresLocalNetworkPermission(urlString: String): Boolean =
withContext(Dispatchers.IO) {
try {
val host = if (urlString.contains("://")) {
URI(urlString).host
} else {
val afterAt = urlString.substringAfter('@', urlString)
afterAt.substringBefore(':')
}

if (host == null) return@withContext false
if (host == null) return@withContext false

if (host.endsWith(".local", ignoreCase = true)) {
return@withContext true
}
if (host.endsWith(".local", ignoreCase = true)) {
return@withContext true
}

val addresses = InetAddress.getAllByName(host)
val addresses = InetAddress.getAllByName(host)

addresses.any { address ->
address.isSiteLocalAddress ||
address.isLinkLocalAddress
addresses.any { address ->
address.isSiteLocalAddress ||
address.isLinkLocalAddress
}
} catch (_: Exception) {
false
}
} catch (_: Exception) {
false
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ enum class ExtensionType {
Markdown;
}

fun extensionType(extension: String): ExtensionType? = extensionTypeFromNumber(extensionTypeLib(extension))
fun extensionType(extension: String): ExtensionType? =
extensionTypeFromNumber(extensionTypeLib(extension))

private fun extensionTypeFromNumber(num: Int): ExtensionType? =
when (num) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ import java.util.Locale
import java.util.TimeZone


class GithubProvider(

) : Provider {
class GithubProvider : Provider {

override val createRepoLink: String = "https://github.com/new"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,5 @@ sealed interface RemoteDestination : Parcelable {
) : RemoteDestination

@Parcelize
data object Logs: RemoteDestination
data object Logs : RemoteDestination
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid
import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells
import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridItemSpan
import androidx.compose.foundation.lazy.staggeredgrid.rememberLazyStaggeredGridState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.pullrefresh.PullRefreshIndicator
import androidx.compose.material.pullrefresh.pullRefresh
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.material3.TooltipAnchorPosition
import androidx.compose.material3.TooltipBox
import androidx.compose.material3.TooltipDefaults
import androidx.compose.material3.TooltipDefaults.rememberTooltipPositionProvider
import androidx.compose.material3.rememberDrawerState
import androidx.compose.material3.rememberTooltipState
Expand Down Expand Up @@ -438,7 +437,11 @@ private fun SyncStateIcon(
}

val tooltipState = rememberTooltipState(isPersistent = true)
var visible by remember(state) { if (state is Ok) mutableStateOf(!state.isConsumed) else mutableStateOf(true) }
var visible by remember(state) {
if (state is Ok) mutableStateOf(!state.isConsumed) else mutableStateOf(
true
)
}

if (state is Ok) {
LaunchedEffect(visible) {
Expand Down Expand Up @@ -482,16 +485,19 @@ private fun SyncStateIcon(
contentDescription = "Sync Error",
modifier = modifier
)

is Ok -> Icon(
imageVector = Icons.Default.CloudDone,
contentDescription = "Sync Done",
modifier = modifier,
)

Pull -> Icon(
imageVector = Icons.Default.CloudDownload,
contentDescription = "Pulling",
modifier = modifier,
)

Push -> Icon(
imageVector = Icons.Default.CloudUpload,
contentDescription = "Pushing",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ fun MarkdownCustom(
)
}
}

@Composable
fun MarkdownCustomInner(
content: String,
Expand All @@ -82,7 +83,13 @@ fun MarkdownCustomInner(
annotator: MarkdownAnnotator = markdownAnnotator(),
extendedSpans: MarkdownExtendedSpans = markdownExtendedSpans(),
inlineContent: MarkdownInlineContent = markdownInlineContent(),
components: MarkdownComponents = markdownComponents(checkbox = { MarkdownCheckBox(it.content, it.node, it.typography.text) }),
components: MarkdownComponents = markdownComponents(checkbox = {
MarkdownCheckBox(
it.content,
it.node,
it.typography.text
)
}),
animations: MarkdownAnimations = markdownAnimations(),
referenceLinkHandler: ReferenceLinkHandler = ReferenceLinkHandlerImpl(),
lookupLinks: Boolean = true,
Expand Down Expand Up @@ -114,7 +121,6 @@ fun MarkdownCustomInner(
)



private fun TextStyle.scaled(scale: Float): TextStyle = copy(
fontSize = fontSize.scale(scale),
lineHeight = lineHeight.scale(scale),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,12 @@ private fun getTextStyleFromInt(id: Int): TextStyle {
fontSize = 8.sp,
lineHeight = 10.sp
)

0 -> MaterialTheme.typography.bodySmall.copy(
fontSize = 10.sp,
lineHeight = 12.sp
)

1 -> MaterialTheme.typography.bodySmall
2 -> MaterialTheme.typography.bodyMedium
3 -> MaterialTheme.typography.bodyLarge
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package io.github.wiiznokes.gitnote.ui.screen.setup
import androidx.compose.animation.ContentTransform
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.lifecycle.viewmodel.compose.viewModel
import dev.olshevski.navigation.reimagined.AnimatedNavHost
Expand All @@ -14,6 +15,7 @@ import dev.olshevski.navigation.reimagined.navigate
import dev.olshevski.navigation.reimagined.pop
import dev.olshevski.navigation.reimagined.popUpTo
import dev.olshevski.navigation.reimagined.rememberNavController
import io.github.wiiznokes.gitnote.ui.component.RequestConfirmationDialog
import io.github.wiiznokes.gitnote.ui.destination.NewRepoMethod
import io.github.wiiznokes.gitnote.ui.destination.SetupDestination
import io.github.wiiznokes.gitnote.ui.model.StorageConfiguration
Expand Down Expand Up @@ -84,6 +86,35 @@ fun SetupNav(
key = path
)

val requestConfirmationDialogExpanded = remember {
mutableStateOf(false)
}

var pendingStorageConfig: StorageConfiguration? = remember {
null
}

RequestConfirmationDialog(
expanded = requestConfirmationDialogExpanded,
text = "WARNING: Are you sure you want to continue? The directory will be deleted.",
onConfirmation = {
pendingStorageConfig?.let { storageConfig ->
when (setupDestination.newRepoMethod) {
NewRepoMethod.Create -> vm.createLocalRepo(
storageConfig,
onSetupSuccess
)

NewRepoMethod.Open -> vm.openRepo(storageConfig, onSetupSuccess)
NewRepoMethod.Clone -> {
navController.navigate(
SetupDestination.Remote(storageConfig)
)
}
}
}
}
)

FileExplorerScreen(
currentDir = fileExplorerVm.currentDir,
Expand All @@ -102,14 +133,24 @@ fun SetupNav(
)

when (setupDestination.newRepoMethod) {
NewRepoMethod.Create -> vm.createLocalRepo(
storageConfig,
onSetupSuccess
)
NewRepoMethod.Create -> {
if (vm.isFolderWillBeDeleted(storageConfig)) {
requestConfirmationDialogExpanded.value = true
pendingStorageConfig = storageConfig
} else {
vm.createLocalRepo(
storageConfig,
onSetupSuccess
)
}
}

NewRepoMethod.Open -> vm.openRepo(storageConfig, onSetupSuccess)
NewRepoMethod.Clone -> {
if (useUrlForRootFolder || vm.checkPathForClone(storageConfig.repoPath()).isSuccess) {
if (vm.isFolderWillBeDeleted(storageConfig)) {
requestConfirmationDialogExpanded.value = true
pendingStorageConfig = storageConfig
} else {
navController.navigate(
SetupDestination.Remote(storageConfig)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ import androidx.compose.ui.tooling.preview.Preview
import io.github.wiiznokes.gitnote.MyApp
import io.github.wiiznokes.gitnote.R
import io.github.wiiznokes.gitnote.helper.NetworkPermissionHelper
import kotlinx.coroutines.launch
import io.github.wiiznokes.gitnote.manager.getUrlInfoLib
import io.github.wiiznokes.gitnote.provider.GithubProvider
import io.github.wiiznokes.gitnote.provider.Provider
import io.github.wiiznokes.gitnote.ui.component.AppPage
import io.github.wiiznokes.gitnote.ui.component.SetupButton
import io.github.wiiznokes.gitnote.ui.component.SetupLine
import io.github.wiiznokes.gitnote.ui.component.SetupPage
import kotlinx.coroutines.launch


fun isUrlSsh(url: String): Boolean {
Expand Down Expand Up @@ -134,7 +134,10 @@ fun EnterUrlScreen(
onClick = {
val urlText = url.value.text
scope.launch {
if (NetworkPermissionHelper.requiresLocalNetworkPermission(urlText) && !NetworkPermissionHelper.isPermissionGranted(context)) {
if (NetworkPermissionHelper.requiresLocalNetworkPermission(urlText) && !NetworkPermissionHelper.isPermissionGranted(
context
)
) {
pendingUrl.value = urlText
nearbyPermissionLauncher.launch(android.Manifest.permission.ACCESS_LOCAL_NETWORK)
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import io.github.wiiznokes.gitnote.ui.destination.RemoteDestination.PickRepo
import io.github.wiiznokes.gitnote.ui.destination.RemoteDestination.SelectGenerateNewSshKeys
import io.github.wiiznokes.gitnote.ui.destination.RemoteDestination.SelectProvider
import io.github.wiiznokes.gitnote.ui.destination.RemoteDestination.SelectSetupAutomatically
import io.github.wiiznokes.gitnote.ui.destination.SettingsDestination
import io.github.wiiznokes.gitnote.ui.model.StorageConfiguration
import io.github.wiiznokes.gitnote.ui.screen.settings.LogsScreen
import io.github.wiiznokes.gitnote.ui.utils.slide
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import io.github.wiiznokes.gitnote.data.room.RepoDatabase
import io.github.wiiznokes.gitnote.helper.NameValidation
import io.github.wiiznokes.gitnote.manager.StorageManager
import io.github.wiiznokes.gitnote.ui.model.FileExtension
import io.github.wiiznokes.gitnote.ui.model.NoteViewType
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,30 @@ class SetupViewModel(val authFlow: SharedFlow<String>) : ViewModel(), SetupViewM
}
}

fun isFolderWillBeDeleted(storageConfig: StorageConfiguration): Boolean {
return when (storageConfig) {
StorageConfiguration.App -> false
is StorageConfiguration.Device -> {
if (storageConfig.useUrlForRootFolder) {
return false
}

val folder = NodeFs.Folder.fromPath(storageConfig.path)

if (!folder.exist()) {
return false
}


if (folder.isEmptyDirectory().isSuccess) {
return false
}

true
}
}
}

fun createLocalRepo(storageConfig: StorageConfiguration, onSuccess: () -> Unit) {

CoroutineScope(Dispatchers.IO).launch {
Expand Down Expand Up @@ -158,15 +182,6 @@ class SetupViewModel(val authFlow: SharedFlow<String>) : ViewModel(), SetupViewM

}


fun checkPathForClone(repoPath: String): Result<Unit> {
val result = NodeFs.Folder.fromPath(repoPath).isEmptyDirectory()
result.onFailure {
uiHelper.makeToast(it.message)
}
return result
}

override fun launch(f: suspend () -> Unit) {
viewModelScope.launch { f() }
}
Expand Down