Skip to content

Commit

Permalink
* Outsourced theming to RetainTheme!
Browse files Browse the repository at this point in the history
* Dropbox sync!
* Split up SettingsViewModel into SFTP/Dropbox/Nextcloud viewmodels!
  • Loading branch information
Eboreg committed Jul 31, 2023
1 parent 7bf48b6 commit 6569fea
Show file tree
Hide file tree
Showing 57 changed files with 1,302 additions and 986 deletions.
10 changes: 5 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
*.iml
.DS_Store
.cxx
.externalNativeBuild
.gradle
/local.properties
/.idea
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
keystore.properties
local.properties
/keystore.properties
/notes.txt
secrets.properties

# Built application files
*.apk
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Retain

It's a note/checklist app. Heavily inspired by Google Keep, except it's not evil (i.e. open source, doesn't track you). You can sync your notes to a Nextcloud account if you so desire.
It's a note/checklist app. Heavily inspired by Google Keep, except it's not evil (i.e. open source, doesn't track you). You can sync your notes to a Nextcloud, SFTP, or Dropbox account if you so desire.

Not yet available on any appstores etc. But it will probably come. Don't get your knickers in a twist!

Expand Down
54 changes: 37 additions & 17 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import java.io.FileInputStream
import java.util.Properties

val keystoreProperties = Properties()
val secretsProperties = Properties()

keystoreProperties.load(FileInputStream(rootProject.file("keystore.properties")))
secretsProperties.load(FileInputStream(rootProject.file("secrets.properties")))

plugins {
id("com.android.application")
Expand All @@ -16,7 +19,7 @@ plugins {
}

kotlin {
jvmToolchain(8)
jvmToolchain(17)
}

android {
Expand All @@ -32,37 +35,50 @@ android {
compileSdk = 33

defaultConfig {
// val dropboxAppKey = secretsProperties["dropboxAppKey"] as String

applicationId = "us.huseli.retain"
minSdk = 26
targetSdk = 33
versionCode = 1
versionName = "1.0"
versionName = "1.0.0-beta.1"
vectorDrawables.useSupportLibrary = true
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
// buildConfigField("String", "dropboxAppKey", "\"${dropboxAppKey}\"")
// manifestPlaceholders["dropboxAppKey"] = dropboxAppKey
setProperty("archivesBaseName", "retain_$versionName")
}

buildTypes {
debug {
val dropboxAppKey = secretsProperties["dropboxAppKeyDebug"] as String

isDebuggable = true
isRenderscriptDebuggable = true
applicationIdSuffix = ".debug"
buildConfigField("String", "dropboxAppKey", "\"${dropboxAppKey}\"")
manifestPlaceholders["dropboxAppKey"] = dropboxAppKey
}
release {
val dropboxAppKey = secretsProperties["dropboxAppKey"] as String

proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
signingConfig = signingConfigs.getByName("release")
buildConfigField("String", "dropboxAppKey", "\"${dropboxAppKey}\"")
manifestPlaceholders["dropboxAppKey"] = dropboxAppKey
}
}

compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}

kotlinOptions {
jvmTarget = "1.8"
jvmTarget = "17"
}

buildFeatures {
Expand All @@ -85,12 +101,11 @@ dependencies {
implementation("com.google.devtools.ksp:symbol-processing-api:1.8.10-1.0.9")
implementation("androidx.core:core-ktx:1.10.1")
implementation("androidx.core:core-splashscreen:1.0.1")
implementation("org.burnoutcrew.composereorderable:reorderable:0.9.6")
implementation("androidx.recyclerview:recyclerview:1.3.0")
implementation("androidx.recyclerview:recyclerview:1.3.1")
implementation("androidx.preference:preference-ktx:1.2.0")
implementation("androidx.activity:activity-compose:1.7.2")
implementation("androidx.navigation:navigation-compose:2.5.3")
// For PickVisualMedia contract
implementation("androidx.navigation:navigation-compose:2.6.0")
// For PickVisualMedia contract:
implementation("androidx.activity:activity-ktx:1.7.2")

// Lifecycle:
Expand All @@ -106,23 +121,22 @@ dependencies {
}

// Compose:
implementation(platform("androidx.compose:compose-bom:2023.05.01"))
implementation("androidx.compose.ui:ui:1.4.3")
implementation("androidx.compose.ui:ui-graphics:1.4.3")
implementation("androidx.compose.ui:ui-tooling-preview:1.4.3")
implementation("androidx.compose.material3:material3:1.1.0")
androidTestImplementation(platform("androidx.compose:compose-bom:2023.05.01"))
androidTestImplementation("androidx.compose.ui:ui-test-junit4:1.4.3")
debugImplementation("androidx.compose.ui:ui-tooling:1.4.3")
debugImplementation("androidx.compose.ui:ui-test-manifest:1.4.3")

// Material:
implementation("androidx.compose.material:material:1.4.3")
implementation("androidx.compose.material3:material3:1.1.0")
implementation("androidx.compose.material3:material3:1.1.1")
implementation("androidx.compose.material:material-icons-extended:1.4.3")

// Room:
implementation("androidx.room:room-runtime:2.5.1")
ksp("androidx.room:room-compiler:2.5.1")
implementation("androidx.room:room-ktx:2.5.1")
implementation("androidx.room:room-runtime:2.5.2")
ksp("androidx.room:room-compiler:2.5.2")
implementation("androidx.room:room-ktx:2.5.2")

// Hilt:
implementation("com.google.dagger:hilt-android:2.46.1")
Expand All @@ -145,7 +159,13 @@ dependencies {
// SFTP:
implementation(group = "com.github.mwiede", name = "jsch", version = "0.2.9")

// Dropbox:
implementation("com.dropbox.core:dropbox-core-sdk:5.4.5")

// Theme:
implementation("com.github.Eboreg:RetainTheme:1.1.3")

// testImplementation("junit:junit:4.13.2")
// androidTestImplementation("androidx.test.ext:junit:1.1.5")
// androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
}
}
24 changes: 23 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />

<application
android:name=".Application"
Expand All @@ -24,6 +25,24 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<activity
android:name="com.dropbox.core.android.AuthActivity"
android:exported="true"
android:configChanges="orientation|keyboard"
android:launchMode="singleTask">
<intent-filter>
<data android:scheme="db-${dropboxAppKey}" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

<provider
android:authorities="${applicationId}.fileprovider"
android:name="androidx.core.content.FileProvider"
Expand All @@ -35,4 +54,7 @@
</provider>
</application>

</manifest>
<queries>
<package android:name="com.dropbox.android" />
</queries>
</manifest>
5 changes: 3 additions & 2 deletions app/src/main/java/us/huseli/retain/Constants.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ package us.huseli.retain
object Constants {
const val DEFAULT_MAX_IMAGE_DIMEN = 2048
const val DEFAULT_MIN_COLUMN_WIDTH = 180
const val DEFAULT_NEXTCLOUD_BASE_DIR = "/.retain"
const val DEFAULT_SFTP_BASE_DIR = ".retain"
const val IMAGE_SUBDIR = "images"
const val NAV_ARG_IMAGE_CAROUSEL_CURRENT_ID = "imageCarouselCurrentId"
const val NAV_ARG_NOTE_ID = "noteId"
const val NEXTCLOUD_BASE_DIR = "/.retain"
const val PREF_DROPBOX_CREDENTIAL = "dropboxCredential"
const val PREF_MIN_COLUMN_WIDTH = "minColumnWidth"
const val PREF_NEXTCLOUD_BASE_DIR = "nextCloudBaseDir"
const val PREF_NEXTCLOUD_PASSWORD = "nextCloudPassword"
Expand All @@ -18,7 +20,6 @@ object Constants {
const val PREF_SFTP_PORT = "sftpPort"
const val PREF_SFTP_USERNAME = "sftpUsername"
const val PREF_SYNC_BACKEND = "syncBackend"
const val SFTP_BASE_DIR = ".retain"
const val SYNCBACKEND_IMAGE_SUBDIR = "images"
const val SYNCBACKEND_JSON_SUBDIR = "json"
const val ZIP_BUFFER_SIZE = 2048
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/us/huseli/retain/Enums.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ object Enums {
NONE("None"),
NEXTCLOUD("Nextcloud"),
SFTP("SFTP"),
DROPBOX("Dropbox"),
}
}
18 changes: 8 additions & 10 deletions app/src/main/java/us/huseli/retain/Logger.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ data class LogMessage(
fun levelToString() = logLevelToString(level)
override fun toString() = "$timestamp ${levelToString()} $tag [$thread] $message"
override fun equals(other: Any?) = other is LogMessage && other.timestamp == timestamp
override fun hashCode() = timestamp.hashCode()
override fun hashCode(): Int = 31 * timestamp.hashCode() + message.hashCode()
}

@Singleton
Expand Down Expand Up @@ -73,19 +73,17 @@ class Logger {
interface LogInterface {
val logger: Logger

fun log(message: String, level: Int = Log.INFO, showInSnackbar: Boolean = false) {
log(createLogMessage(message, level), showInSnackbar)
}
fun log(message: String, level: Int = Log.INFO, showInSnackbar: Boolean = false) =
logger.log(createLogMessage(message, level), showInSnackbar)

fun log(logMessage: LogMessage, showInSnackbar: Boolean = false) = logger.log(logMessage, showInSnackbar)
fun showError(message: String) = log(message, Log.ERROR, true)

fun logError(prefix: String, logMessage: LogMessage? = null) {
var message = prefix
if (logMessage != null) message += ": ${logMessage.message}"
log(message, Log.ERROR, true)
fun showError(prefix: String, exception: Exception?) {
if (exception != null) showError("$prefix: $exception")
else showError(prefix)
}

fun createLogMessage(message: String, level: Int = Log.INFO): LogMessage {
private fun createLogMessage(message: String, level: Int = Log.INFO): LogMessage {
return LogMessage(
level = level,
tag = "${javaClass.simpleName}<${System.identityHashCode(this)}>",
Expand Down
8 changes: 8 additions & 0 deletions app/src/main/java/us/huseli/retain/RetainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ import androidx.activity.compose.setContent
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import dagger.hilt.android.AndroidEntryPoint
import us.huseli.retain.compose.App
import us.huseli.retain.syncbackend.DropboxEngine
import javax.inject.Inject

@AndroidEntryPoint
class RetainActivity : ComponentActivity() {
@Inject
lateinit var logger: Logger
@Inject
lateinit var dropboxEngine: DropboxEngine

override fun onCreate(savedInstanceState: Bundle?) {
installSplashScreen()
Expand All @@ -21,4 +24,9 @@ class RetainActivity : ComponentActivity() {
App(logger)
}
}

override fun onResume() {
super.onResume()
dropboxEngine.onResume()
}
}
2 changes: 1 addition & 1 deletion app/src/main/java/us/huseli/retain/compose/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import us.huseli.retaintheme.ui.theme.RetainTheme
import us.huseli.retain.ChecklistNoteDestination
import us.huseli.retain.DebugDestination
import us.huseli.retain.Enums.NoteType
Expand All @@ -19,7 +20,6 @@ import us.huseli.retain.TextNoteDestination
import us.huseli.retain.compose.notescreen.ChecklistNoteScreen
import us.huseli.retain.compose.notescreen.TextNoteScreen
import us.huseli.retain.compose.settings.SettingsScreen
import us.huseli.retain.ui.theme.RetainTheme
import us.huseli.retain.viewmodels.NoteViewModel
import us.huseli.retain.viewmodels.SettingsViewModel
import java.util.UUID
Expand Down
15 changes: 4 additions & 11 deletions app/src/main/java/us/huseli/retain/compose/HomeScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
Expand Down Expand Up @@ -58,7 +57,7 @@ fun HomeScreen(
onDebugClick: () -> Unit,
) {
val syncBackend by viewModel.syncBackend.collectAsStateWithLifecycle()
val isSyncBackendRefreshing by viewModel.isSyncBackendRefreshing.collectAsStateWithLifecycle(false)
val isSyncBackendSyncing by viewModel.isSyncBackendSyncing.collectAsStateWithLifecycle(false)
val isSyncBackendEnabled by settingsViewModel.isSyncBackendEnabled.collectAsStateWithLifecycle(false)
val notes by viewModel.notes.collectAsStateWithLifecycle(emptyList())
val images by viewModel.images.collectAsStateWithLifecycle(emptyList())
Expand All @@ -81,7 +80,7 @@ fun HomeScreen(

if (isSyncBackendEnabled) {
val refreshState = rememberPullRefreshState(
refreshing = isSyncBackendRefreshing,
refreshing = isSyncBackendSyncing,
onRefresh = { viewModel.syncBackend() },
)
lazyModifier = lazyModifier.pullRefresh(state = refreshState)
Expand Down Expand Up @@ -115,7 +114,6 @@ fun HomeScreen(

RetainScaffold(
viewModel = viewModel,
settingsViewModel = settingsViewModel,
topBar = {
if (isSelectEnabled) SelectionTopAppBar(
selectedCount = selectedNoteIds.size,
Expand Down Expand Up @@ -156,17 +154,14 @@ fun HomeScreen(
}

Column(modifier = lazyModifier.padding(innerPadding).fillMaxWidth()) {
if (isSyncBackendRefreshing) {
if (isSyncBackendSyncing) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = stringResource(
R.string.syncing_with,
syncBackend?.displayName ?: stringResource(R.string.backend)
),
text = stringResource(R.string.syncing_with, syncBackend.displayName),
style = MaterialTheme.typography.bodySmall,
modifier = Modifier.padding(end = 4.dp),
)
Expand All @@ -177,7 +172,6 @@ fun HomeScreen(
if (viewType == HomeScreenViewType.GRID) {
LazyVerticalStaggeredGrid(
columns = StaggeredGridCells.Adaptive(minSize = minColumnWidth.dp),
contentPadding = PaddingValues(8.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalItemSpacing = 8.dp,
) {
Expand All @@ -187,7 +181,6 @@ fun HomeScreen(
LazyColumn(
modifier = Modifier.reorderable(reorderableState).detectReorder(reorderableState),
state = reorderableState.listState,
contentPadding = PaddingValues(8.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
items(notes, key = { it.id }) { note ->
Expand Down
Loading

0 comments on commit 6569fea

Please sign in to comment.