Skip to content

Commit

Permalink
feat(editor): add manual bookmark option and improve editor UI
Browse files Browse the repository at this point in the history
feat(settings): show server URL in logout section
refactor(sync): remove TODO comments and update sync message
docs: improve README development status section
fix(json): prevent empty image processing in backend
  • Loading branch information
DesarrolloAntonio committed Dec 18, 2024
1 parent 72b293c commit a8b41cf
Show file tree
Hide file tree
Showing 13 changed files with 149 additions and 69 deletions.
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,10 @@ Shiori is built using a variety of modern and robust technologies to ensure scal
- **Protobuf (Proto)**: For efficient data serialization.
-
## Development Status ⚠️
Please note that Shiori is currently under active development. While we strive to provide a stable experience, you may encounter bugs or incomplete features. We encourage users to:
Please note that Shiori is currently under development. While we strive to provide a stable experience, you may encounter bugs or incomplete features. We encourage users to:
- Report any issues you find on our [GitHub Issues page](https://github.com/DesarrolloAntonio/Shiori-Android-Client/issues)
- Be aware that some features might be unstable or work in progress
- Expect regular updates as we continue to improve the application
- Back up your data regularly during this development phase

## Download

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,21 @@ import com.google.gson.GsonBuilder
import com.desarrollodroide.data.helpers.TagTypeAdapter
import com.desarrollodroide.model.Bookmark
import com.desarrollodroide.model.Tag
import com.google.gson.ExclusionStrategy
import com.google.gson.FieldAttributes

fun Bookmark.toBodyJson() = GsonBuilder()
/**
* Converts Bookmark to JSON, omitting the imageURL field when empty
* to prevent empty image generation processing in the backend.
*
* @return String containing the JSON representation of the Bookmark
*/
fun Bookmark.toBodyJson() = GsonBuilder()
.registerTypeAdapter(Tag::class.java, TagTypeAdapter())
.create().toJson(this)
.setExclusionStrategies(object : ExclusionStrategy {
override fun shouldSkipField(f: FieldAttributes) =
f.name == "imageURL" && this@toBodyJson.imageURL.isEmpty()
override fun shouldSkipClass(clazz: Class<*>?) = false
})
.create()
.toJson(this)
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ android.nonTransitiveRClass=true
compileSdkVersion=34
minSdkVersion=26
targetSdkVersion=34
versionCode=47
versionName=1.50.01
versionCode=48
versionName=1.50.10

android.defaults.buildfeatures.buildconfig=true
android.nonFinalResIds=false
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import com.desarrollodroide.pagekeeper.navigation.Navigation
import org.koin.android.ext.android.inject
import com.desarrollodroide.pagekeeper.extensions.shareEpubFile
import com.desarrollodroide.pagekeeper.extensions.shareText
import com.desarrollodroide.pagekeeper.ui.bookmarkeditor.BookmarkEditorActivity
import java.util.Locale

class MainActivity : ComponentActivity() {
Expand Down Expand Up @@ -49,6 +50,9 @@ class MainActivity : ComponentActivity() {
},
shareText = {
shareText(it)
},
onAddManuallyClick = {
startActivity(BookmarkEditorActivity.createManualIntent(this))
}
)
}
Expand All @@ -59,7 +63,7 @@ class MainActivity : ComponentActivity() {
override fun onResume() {
super.onResume()
Log.v("MainActivity", "onResume")
// TODO: sync
// TODO: sync when endpoint is available
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import java.io.File
fun Navigation(
onFinish: () -> Unit,
openUrlInBrowser: (String) -> Unit,
onAddManuallyClick: () -> Unit,
shareEpubFile: (File) -> Unit,
shareText: (String) -> Unit
) {
Expand Down Expand Up @@ -56,7 +57,8 @@ fun Navigation(
onFinish = onFinish,
openUrlInBrowser = openUrlInBrowser,
shareEpubFile = shareEpubFile,
shareText = shareText
shareText = shareText,
onAddManuallyClick = onAddManuallyClick
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.desarrollodroide.pagekeeper.ui.bookmarkeditor

import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.util.Log
Expand All @@ -24,8 +25,25 @@ class BookmarkEditorActivity : ComponentActivity() {

private val bookmarkViewModel: BookmarkViewModel by viewModel()

companion object {
const val EXTRA_MODE = "extra_mode"

fun createManualIntent(context: Context): Intent {
return Intent(context, BookmarkEditorActivity::class.java).apply {
putExtra(EXTRA_MODE, BookmarkEditorType.ADD_MANUALLY.name)
}
}
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

val mode = intent.getStringExtra(EXTRA_MODE)
if (mode == BookmarkEditorType.ADD_MANUALLY.name) {
setupBookmarkEditor(BookmarkEditorType.ADD_MANUALLY, "", "")
return
}

var sharedUrl = ""
var title = ""
intent?.let { intent ->
Expand All @@ -43,6 +61,7 @@ class BookmarkEditorActivity : ComponentActivity() {
finish()
}
}

lifecycleScope.launch {
bookmarkViewModel.toastMessage.collect { message ->
message?.let {
Expand All @@ -51,50 +70,18 @@ class BookmarkEditorActivity : ComponentActivity() {
}
}
}

lifecycleScope.launch {
if (sharedUrl.isNotEmpty()) {
if (bookmarkViewModel.userHasSession()) {
if (bookmarkViewModel.autoAddBookmark) {
// Auto-add bookmark without showing the editor screen
bookmarkViewModel.autoAddBookmark(sharedUrl, title)
Toast.makeText(this@BookmarkEditorActivity, "Bookmark saved", Toast.LENGTH_LONG).show()
finish()
} else {
// Show the bookmark editor screen
setContent {
ShioriTheme {
Surface(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.inverseOnSurface)
) {
val makeArchivePublic = bookmarkViewModel.makeArchivePublic
val createEbook = bookmarkViewModel.createEbook
val createArchive = bookmarkViewModel.createArchive
BookmarkEditorScreen(
title = "Add",
bookmarkEditorType = BookmarkEditorType.ADD,
bookmark = Bookmark(
url = sharedUrl,
title = title,
tags = emptyList(),
public = if (makeArchivePublic) 1 else 0,
createArchive = createArchive,
createEbook = createEbook
),
onBack = { finish() },
updateBookmark = { finish() },
showToast = { message ->
Toast.makeText(this@BookmarkEditorActivity, message, Toast.LENGTH_LONG).show()
},
startMainActivity = { startMainActivity() }
)
}
}
}
setupBookmarkEditor(BookmarkEditorType.ADD, sharedUrl, title)
}
} else {
// User doesn't have a session, show login screen
setContent {
ShioriTheme {
NotSessionScreen(
Expand All @@ -106,13 +93,46 @@ class BookmarkEditorActivity : ComponentActivity() {
}
}
} else {
// No shared URL, finish the activity
Toast.makeText(this@BookmarkEditorActivity, "No shared URL found", Toast.LENGTH_LONG).show()
finish()
}
}
}

private fun setupBookmarkEditor(type: BookmarkEditorType, url: String, title: String) {
setContent {
ShioriTheme {
Surface(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.inverseOnSurface)
) {
val makeArchivePublic = bookmarkViewModel.makeArchivePublic
val createEbook = bookmarkViewModel.createEbook
val createArchive = bookmarkViewModel.createArchive
BookmarkEditorScreen(
title = if (type == BookmarkEditorType.ADD_MANUALLY) "Add Manually" else "Add",
bookmarkEditorType = type,
bookmark = Bookmark(
url = url,
title = title,
tags = emptyList(),
public = if (makeArchivePublic) 1 else 0,
createArchive = createArchive,
createEbook = createEbook
),
onBack = { finish() },
updateBookmark = { finish() },
showToast = { message ->
Toast.makeText(this@BookmarkEditorActivity, message, Toast.LENGTH_LONG).show()
},
startMainActivity = { startMainActivity() }
)
}
}
}
}

private fun startMainActivity() {
val intent = Intent(this, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ fun BookmarkEditorScreen(
val newTag = remember { mutableStateOf("") }
val availableTags = bookmarkViewModel.availableTags.collectAsState()
val bookmarkUiState = bookmarkViewModel.bookmarkUiState.collectAsState().value
var currentUrl by remember { mutableStateOf(bookmark.url) }

// No need to update values in settings
var localMakeArchivePublic by remember { mutableStateOf(bookmarkViewModel.makeArchivePublic) }
Expand Down Expand Up @@ -66,15 +67,16 @@ fun BookmarkEditorScreen(

BookmarkEditorView(
title = title,
url = currentUrl,
bookmarkEditorType = bookmarkEditorType,
newTag = newTag,
assignedTags = assignedTags,
availableTags = availableTags,
saveBookmark = {
when (bookmarkEditorType) {
BookmarkEditorType.ADD -> {
BookmarkEditorType.ADD, BookmarkEditorType.ADD_MANUALLY -> {
bookmarkViewModel.saveBookmark(
url = bookmark.url,
url = currentUrl,
title = bookmark.title,
tags = assignedTags.value,
createArchive = localCreateArchive,
Expand All @@ -100,9 +102,9 @@ fun BookmarkEditorScreen(
makeArchivePublic = localMakeArchivePublic,
onMakeArchivePublicChanged = { localMakeArchivePublic = it },
createEbook = localCreateEbook,
url = bookmark.url,
onCreateEbookChanged = { localCreateEbook = it },
onCreateArchiveChanged = { localCreateArchive = it }
onCreateArchiveChanged = { localCreateArchive = it },
onUrlChange = { currentUrl = it }
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import com.desarrollodroide.pagekeeper.ui.components.Categories
import com.desarrollodroide.pagekeeper.ui.components.CategoriesType
import com.desarrollodroide.model.Tag

enum class BookmarkEditorType { ADD, EDIT }
enum class BookmarkEditorType { ADD, ADD_MANUALLY, EDIT }
@Composable
fun BookmarkEditorView(
title: String,
Expand All @@ -64,6 +64,7 @@ fun BookmarkEditorView(
onMakeArchivePublicChanged: (Boolean) -> Unit,
createEbook: Boolean,
onCreateEbookChanged: (Boolean) -> Unit,
onUrlChange: (String) -> Unit = {}
) {
Column(
modifier = Modifier
Expand Down Expand Up @@ -92,16 +93,28 @@ fun BookmarkEditorView(
Icon(Icons.Outlined.Save, contentDescription = "Save")
}
}
Text(
text = url,
color = MaterialTheme.colorScheme.onSurface,
modifier = Modifier
.fillMaxWidth()
.background(MaterialTheme.colorScheme.surfaceVariant)
.padding(8.dp),
maxLines = 3,
overflow = TextOverflow.Ellipsis //
)
if (bookmarkEditorType == BookmarkEditorType.ADD_MANUALLY) {
OutlinedTextField(
value = url,
onValueChange = onUrlChange,
label = { Text("URL") },
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp),
singleLine = true
)
} else {
Text(
text = url,
color = MaterialTheme.colorScheme.onSurface,
modifier = Modifier
.fillMaxWidth()
.background(MaterialTheme.colorScheme.surfaceVariant)
.padding(8.dp),
maxLines = 3,
overflow = TextOverflow.Ellipsis
)
}

if (bookmarkEditorType == BookmarkEditorType.ADD) {
Row(verticalAlignment = CenterVertically) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ class FeedViewModel(
fun refreshFeed() {
viewModelScope.launch {
val localBookmarkIds = bookmarkDatabase.getAllBookmarkIds()
// TODO sync disabled until endpoint finished
syncBookmarks(localBookmarkIds, settingsPreferenceDataSource.getLastSyncTimestamp())
// TODO remove with sync is completed in backend
retrieveAllRemoteBookmarks()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import org.koin.androidx.compose.get
import androidx.compose.runtime.*
import androidx.compose.material3.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Search
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material.icons.filled.Sync
Expand Down Expand Up @@ -86,6 +87,7 @@ fun HomeScreen(
goToLogin: () -> Unit,
onFinish: () -> Unit,
openUrlInBrowser: (String) -> Unit,
onAddManuallyClick: () -> Unit,
shareEpubFile: (File) -> Unit,
shareText: (String) -> Unit
) {
Expand Down Expand Up @@ -146,7 +148,8 @@ fun HomeScreen(
bottomSheetState.show()
}
},
pendingJobs = pendingJobs
pendingJobs = pendingJobs,
onAddManuallyClick = onAddManuallyClick,
)
}
}
Expand Down Expand Up @@ -262,6 +265,7 @@ fun HomeScreen(
fun TopBar(
toggleCategoryVisibility: () -> Unit,
toggleSearchBarVisibility: () -> Unit,
onAddManuallyClick: () -> Unit,
onSettingsClick: () -> Unit,
onSyncButtonClick: () -> Unit,
scrollBehavior: TopAppBarScrollBehavior,
Expand Down Expand Up @@ -309,6 +313,13 @@ fun TopBar(
)
},
actions = {
IconButton(onClick = onAddManuallyClick) {
Icon(
imageVector = Icons.Default.Add,
contentDescription = "Add Manually",
tint = MaterialTheme.colorScheme.secondary,
)
}
IconButton(onClick = { toggleSearchBarVisibility() }) {
Icon(
imageVector = Icons.Filled.Search,
Expand Down Expand Up @@ -507,6 +518,7 @@ fun TopBarPreview() {
toggleCategoryVisibility = { },
toggleSearchBarVisibility = { },
onSettingsClick = { },
onAddManuallyClick = { },
scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(),
hasBookmarks = true,
selectedTagsCount = 2,
Expand Down
Loading

0 comments on commit a8b41cf

Please sign in to comment.