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
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ class LocalServerRepositoryImpl(
"",
"",
null,
-1L,
-1L,
"DESC",
"createdAt",
"DESC",
Expand Down Expand Up @@ -148,7 +150,7 @@ class LocalServerRepositoryImpl(
// Count how many links use this tag
val linkCount =
deeprQueries
.getLinksAndTags("", "", "", tag.id, "DESC", "createdAt", "DESC", "createdAt")
.getLinksAndTags("", "", "", tag.id, -1L, -1L, "DESC", "createdAt", "DESC", "createdAt")
.executeAsList()
.size
TagResponse(
Expand Down
293 changes: 196 additions & 97 deletions app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/DeeprItem.kt

Large diffs are not rendered by default.

95 changes: 49 additions & 46 deletions app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/Home.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package com.yogeshpaliyal.deepr.ui.screens.home

import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.R.attr.label
import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.compose.animation.AnimatedVisibility
Expand Down Expand Up @@ -38,6 +36,9 @@ import androidx.compose.material3.PlainTooltip
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SearchBarDefaults
import androidx.compose.material3.SearchBarValue
import androidx.compose.material3.SegmentedButton
import androidx.compose.material3.SegmentedButtonDefaults
import androidx.compose.material3.SingleChoiceSegmentedButtonRow
import androidx.compose.material3.Text
import androidx.compose.material3.TooltipAnchorPosition
import androidx.compose.material3.TooltipBox
Expand Down Expand Up @@ -148,7 +149,8 @@ fun HomeScreen(
if (!sharedText?.url.isNullOrBlank() && selectedLink == null) {
val normalizedLink = normalizeLink(sharedText.url)
if (isValidDeeplink(normalizedLink)) {
selectedLink = createDeeprObject(link = normalizedLink, name = sharedText.title ?: "")
selectedLink =
createDeeprObject(link = normalizedLink, name = sharedText.title ?: "")
} else {
Toast
.makeText(context, "Invalid deeplink from shared content", Toast.LENGTH_SHORT)
Expand Down Expand Up @@ -255,6 +257,31 @@ fun HomeScreen(
}
},
)

val favouriteFilter by viewModel.favouriteFilter.collectAsStateWithLifecycle()
// Favourite filter tabs
SingleChoiceSegmentedButtonRow(modifier = Modifier.fillMaxWidth().padding(8.dp)) {
SegmentedButton(
shape =
SegmentedButtonDefaults.itemShape(
index = 0,
count = 2,
),
onClick = { viewModel.setFavouriteFilter(-1) },
selected = favouriteFilter == -1,
label = { Text(stringResource(R.string.all)) },
)
SegmentedButton(
shape =
SegmentedButtonDefaults.itemShape(
index = 1,
count = 2,
),
onClick = { viewModel.setFavouriteFilter(1) },
selected = favouriteFilter == 1,
label = { Text(stringResource(R.string.favourites)) },
)
}
}
},
bottomBar = {
Expand Down Expand Up @@ -429,26 +456,23 @@ fun Content(
accounts = accounts!!,
selectedTag = selectedTag,
onItemClick = {
viewModel.incrementOpenedCount(it.id)
openDeeplink(context, it.link)
},
onRemoveClick = {
viewModel.deleteAccount(it.id)
Toast.makeText(context, "Deleted", Toast.LENGTH_SHORT).show()
},
onShortcutClick = {
showShortcutDialog = it
},
onEditClick = editDeepr,
onItemLongClick = {
val clipboard =
context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText("Link copied", it.link)
clipboard.setPrimaryClip(clip)
Toast.makeText(context, "Link copied", Toast.LENGTH_SHORT).show()
},
onQrCodeCLick = {
showQrCodeDialog = it
when (it) {
is MenuItem.Click -> {
viewModel.incrementOpenedCount(it.item.id)
openDeeplink(context, it.item.link)
}
is MenuItem.Delete -> showDeleteConfirmDialog = it.item
is MenuItem.Edit -> editDeepr(it.item)
is MenuItem.FavouriteClick -> viewModel.toggleFavourite(it.item.id)
is MenuItem.ResetCounter -> {
viewModel.resetOpenedCount(it.item.id)
Toast.makeText(context, "Opened count reset", Toast.LENGTH_SHORT).show()
}
is MenuItem.Shortcut -> {
showShortcutDialog = it.item
}
is MenuItem.ShowQrCode -> showQrCodeDialog = it.item
}
},
onTagClick = {
if (viewModel.selectedTagFilter.value?.name == it) {
Expand All @@ -457,13 +481,6 @@ fun Content(
viewModel.setSelectedTagByName(it)
}
},
onResetOpenedCountClick = {
viewModel.resetOpenedCount(it.id)
Toast.makeText(context, "Opened count reset", Toast.LENGTH_SHORT).show()
},
onDeleteClick = {
showDeleteConfirmDialog = it
},
)
}
}
Expand All @@ -473,15 +490,8 @@ fun DeeprList(
accounts: List<GetLinksAndTags>,
selectedTag: Tags?,
contentPaddingValues: PaddingValues,
onItemClick: (GetLinksAndTags) -> Unit,
onRemoveClick: (GetLinksAndTags) -> Unit,
onShortcutClick: (GetLinksAndTags) -> Unit,
onEditClick: (GetLinksAndTags) -> Unit,
onItemLongClick: (GetLinksAndTags) -> Unit,
onQrCodeCLick: (GetLinksAndTags) -> Unit,
onItemClick: (MenuItem) -> Unit,
onTagClick: (String) -> Unit,
onResetOpenedCountClick: (GetLinksAndTags) -> Unit,
onDeleteClick: (GetLinksAndTags) -> Unit,
modifier: Modifier = Modifier,
) {
AnimatedVisibility(
Expand Down Expand Up @@ -544,14 +554,7 @@ fun DeeprList(
account = account,
selectedTag = selectedTag,
onItemClick = onItemClick,
onRemoveClick = onRemoveClick,
onShortcutClick = onShortcutClick,
onEditClick = onEditClick,
onItemLongClick = onItemLongClick,
onQrCodeClick = onQrCodeCLick,
onTagClick = onTagClick,
onResetOpenedCountClick = onResetOpenedCountClick,
onDeleteClick = onDeleteClick,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ fun createDeeprObject(
tagsNames = "",
tagsIds = "",
lastOpenedAt = "",
isFavourite = 0,
)
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,20 @@ class AccountViewModel(
private val _selectedTagFilter = MutableStateFlow<Tags?>(null)
val selectedTagFilter: StateFlow<Tags?> = _selectedTagFilter

// State for favourite filter (-1 = All, 0 = Not Favourite, 1 = Favourite)
private val _favouriteFilter = MutableStateFlow<Int>(-1)
val favouriteFilter: StateFlow<Int> = _favouriteFilter

// Set tag filter
fun setTagFilter(tag: Tags?) {
_selectedTagFilter.value = tag
}

// Set favourite filter
fun setFavouriteFilter(filter: Int) {
_favouriteFilter.value = filter
}

// Remove tag from link
fun removeTagFromLink(
linkId: Long,
Expand Down Expand Up @@ -185,18 +194,23 @@ class AccountViewModel(

@OptIn(ExperimentalCoroutinesApi::class)
val accounts: StateFlow<List<GetLinksAndTags>?> =
combine(searchQuery, sortOrder, selectedTagFilter) { query, sorting, tag ->
Triple(query, sorting, tag)
combine(searchQuery, sortOrder, selectedTagFilter, favouriteFilter) { query, sorting, tag, favourite ->
listOf(query, sorting, tag, favourite)
}.flatMapLatest { combined ->
val sorting = combined.second.split("_")
val query = combined[0] as String
val sorting = (combined[1] as String).split("_")
val tag = combined[2] as Tags?
val favourite = combined[3] as Int
val sortField = sorting.getOrNull(0) ?: "createdAt"
val sortType = sorting.getOrNull(1) ?: "DESC"
deeprQueries
.getLinksAndTags(
combined.first,
combined.first,
combined.third?.id?.toString() ?: "",
combined.third?.id,
query,
query,
tag?.id?.toString() ?: "",
tag?.id,
favourite.toLong(),
favourite.toLong(),
sortType,
sortField,
sortType,
Expand Down Expand Up @@ -293,6 +307,12 @@ class AccountViewModel(
}
}

fun toggleFavourite(id: Long) {
viewModelScope.launch(Dispatchers.IO) {
deeprQueries.toggleFavourite(id)
}
}

fun updateDeeplink(
id: Long,
newLink: String,
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
<string name="qr_scanner">QR Scanner</string>
<string name="tags">Tags</string>
<string name="all">All</string>
<string name="favourites">Favourites</string>
<string name="add_to_favourites">Add to favourites</string>
<string name="remove_from_favourites">Remove from favourites</string>
<string name="add_link">Add Link</string>
<string name="fetch_name_from_link">Fetch name from link</string>
<string name="add_tag">Add Tag</string>
Expand Down
13 changes: 12 additions & 1 deletion app/src/main/sqldelight/com/yogeshpaliyal/deepr/Deepr.sq
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ id INTEGER PRIMARY KEY NOT NULL,
link TEXT NOT NULL,
name TEXT NOT NULL DEFAULT '',
createdAt TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
openedCount INTEGER NOT NULL DEFAULT 0
openedCount INTEGER NOT NULL DEFAULT 0,
isFavourite INTEGER NOT NULL DEFAULT 0
);

CREATE TABLE Tags (
Expand Down Expand Up @@ -39,6 +40,7 @@ SELECT
Deepr.name,
Deepr.createdAt,
Deepr.openedCount,
Deepr.isFavourite,
DOL_Max.lastOpenedAt,
GROUP_CONCAT(Tags.name, ', ') AS tagsNames,
GROUP_CONCAT(Tags.id, ', ') AS tagsIds
Expand All @@ -61,6 +63,9 @@ WHERE
AND (
? = '' OR Tags.id = ?
)
AND (
? = -1 OR Deepr.isFavourite = ?
)
GROUP BY
Deepr.id
ORDER BY
Expand Down Expand Up @@ -191,3 +196,9 @@ INSERT INTO DeeprOpenLog (deeplinkId) VALUES (?);
getLastOpenedTime:
SELECT openedAt FROM DeeprOpenLog WHERE deeplinkId = ? ORDER BY openedAt DESC LIMIT 1;

toggleFavourite:
UPDATE Deepr SET isFavourite = CASE WHEN isFavourite = 0 THEN 1 ELSE 0 END WHERE id = ?;

setFavourite:
UPDATE Deepr SET isFavourite = ? WHERE id = ?;

1 change: 1 addition & 0 deletions app/src/main/sqldelight/migrations/4.sqm
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE Deepr ADD COLUMN isFavourite INTEGER NOT NULL DEFAULT 0;