Skip to content

Commit

Permalink
Follow feed openIn parameter when opening an item from a notification
Browse files Browse the repository at this point in the history
  • Loading branch information
Shinokuni committed Dec 13, 2024
1 parent 144cd9f commit a112e29
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 12 deletions.
2 changes: 1 addition & 1 deletion app/src/main/java/com/readrops/app/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ class MainActivity : ComponentActivity(), KoinComponent {

get<BaseRepository>(parameters = { parametersOf(account) })
.setItemReadState(item)
HomeScreen.openItemScreen(itemId)
HomeScreen.openItem(itemId)
}
}

Expand Down
14 changes: 3 additions & 11 deletions app/src/main/java/com/readrops/app/home/HomeScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import cafe.adriel.voyager.navigator.tab.TabNavigator
import com.readrops.app.R
import com.readrops.app.account.AccountTab
import com.readrops.app.feeds.FeedTab
import com.readrops.app.item.ItemScreen
import com.readrops.app.more.MoreTab
import com.readrops.app.timelime.TimelineTab
import com.readrops.app.util.components.AndroidScreen
Expand All @@ -40,21 +39,13 @@ import kotlinx.coroutines.flow.receiveAsFlow

object HomeScreen : AndroidScreen() {

private val itemChannel = Channel<Int>()
private val tabChannel = Channel<Tab>()

@Composable
override fun Content() {
val navigator = LocalNavigator.currentOrThrow
val scaffoldInsets = WindowInsets.navigationBars.only(WindowInsetsSides.Horizontal)

LaunchedEffect(Unit) {
itemChannel.receiveAsFlow()
.collect {
navigator.push(ItemScreen(it))
}
}

TabNavigator(
tab = TimelineTab
) { tabNavigator ->
Expand Down Expand Up @@ -138,8 +129,9 @@ object HomeScreen : AndroidScreen() {
}
}

suspend fun openItemScreen(itemId: Int) {
itemChannel.send(itemId)
suspend fun openItem(itemId: Int) {
tabChannel.send(TimelineTab)
TimelineTab.openItem(itemId)
}

suspend fun openTab(tab: Tab) {
Expand Down
13 changes: 13 additions & 0 deletions app/src/main/java/com/readrops/app/more/MoreTab.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import cafe.adriel.voyager.navigator.tab.TabOptions
import com.readrops.app.BuildConfig
import com.readrops.app.R
import com.readrops.app.account.selection.adaptiveIconPainterResource
import com.readrops.app.more.debug.DebugScreen
import com.readrops.app.more.preferences.PreferencesScreen
import com.readrops.app.util.components.IconText
import com.readrops.app.util.components.SelectableIconText
Expand Down Expand Up @@ -173,6 +174,18 @@ object MoreTab : Tab, KoinComponent {
tint = MaterialTheme.colorScheme.primary,
onClick = { showDonationDialog = true }
)

if (BuildConfig.DEBUG) {
SelectableIconText(
icon = painterResource(id = R.drawable.ic_bug),
text = "Debug",
style = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.Normal),
spacing = MaterialTheme.spacing.largeSpacing,
padding = MaterialTheme.spacing.mediumSpacing,
tint = MaterialTheme.colorScheme.primary,
onClick = { navigator.push(DebugScreen()) }
)
}
}
}
}
115 changes: 115 additions & 0 deletions app/src/main/java/com/readrops/app/more/debug/DebugScreen.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package com.readrops.app.more.debug

import android.annotation.SuppressLint
import android.app.PendingIntent
import android.content.Intent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationCompat.Builder
import androidx.core.app.NotificationManagerCompat
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
import com.readrops.app.MainActivity
import com.readrops.app.R
import com.readrops.app.ReadropsApp
import com.readrops.app.more.preferences.components.BasePreference
import com.readrops.app.more.preferences.components.PreferenceHeader
import com.readrops.app.sync.SyncWorker.Companion.ACCOUNT_ID_KEY
import com.readrops.app.sync.SyncWorker.Companion.ITEM_ID_KEY
import com.readrops.app.sync.SyncWorker.Companion.SYNC_RESULT_NOTIFICATION_ID
import com.readrops.app.util.components.AndroidScreen
import com.readrops.db.Database
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.get

class DebugScreen : AndroidScreen(), KoinComponent {

@OptIn(ExperimentalMaterial3Api::class)
@SuppressLint("MissingPermission")
@Composable
override fun Content() {
val context = LocalContext.current
val navigator = LocalNavigator.currentOrThrow
val coroutineScope = rememberCoroutineScope()

Scaffold(
topBar = {
TopAppBar(
title = { Text("Debug") },
navigationIcon = {
IconButton(
onClick = { navigator.pop() }
) {
Icon(
imageVector = Icons.AutoMirrored.Default.ArrowBack,
contentDescription = null
)
}
}
)
}
) { paddingValues ->
Column(
modifier = Modifier.padding(paddingValues)
) {
PreferenceHeader(stringResource(R.string.notifications))

BasePreference(
title = "Send notification: Single item from single feed",
onClick = {
coroutineScope.launch {
val database = get<Database>()

val item = database.itemDao().selectFirst()
val account = database.accountDao().selectCurrentAccount().first()

val intent = Intent(context, MainActivity::class.java).apply {
putExtra(ACCOUNT_ID_KEY, account!!.id)
putExtra(ITEM_ID_KEY, item.id)
}

val notificationBuilder = Builder(context, ReadropsApp.SYNC_CHANNEL_ID)
.setContentTitle(item.title)
.setContentText("Test notification")
.setStyle(
NotificationCompat.BigTextStyle().bigText("Test notification")
)
.setSmallIcon(R.drawable.ic_notifications)
.setContentIntent(
PendingIntent.getActivity(
context,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
)
.setAutoCancel(true)

get<NotificationManagerCompat>().notify(
SYNC_RESULT_NOTIFICATION_ID,
notificationBuilder.build()
)
}
}
)
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import com.readrops.db.filters.OrderType
import com.readrops.db.filters.QueryFilters
import com.readrops.db.filters.SubFilter
import com.readrops.db.pojo.ItemWithFeed
import com.readrops.db.queries.ItemSelectionQueryBuilder
import com.readrops.db.queries.ItemsQueryBuilder
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
Expand All @@ -36,6 +37,7 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -441,6 +443,11 @@ class TimelineScreenModel(
preferences.displayNotificationsPermission.write(false)
}
}

suspend fun selectItemWithFeed(itemId: Int): ItemWithFeed? {
val query = ItemSelectionQueryBuilder.buildQuery(itemId, currentAccount!!.config.useSeparateState)
return database.itemDao().selectItemById(query).firstOrNull()
}
}

@Stable
Expand Down
16 changes: 16 additions & 0 deletions app/src/main/java/com/readrops/app/timelime/TimelineTab.kt
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,15 @@ import com.readrops.db.filters.OrderField
import com.readrops.db.filters.OrderType
import com.readrops.db.filters.SubFilter
import com.readrops.db.pojo.ItemWithFeed
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.receiveAsFlow


object TimelineTab : Tab {

private val openItemChannel = Channel<Int>()

override val options: TabOptions
@Composable
get() = TabOptions(
Expand Down Expand Up @@ -118,6 +122,14 @@ object TimelineTab : Tab {
screenModel.disableDisplayNotificationsPermission()
}

LaunchedEffect(Unit) {
openItemChannel.receiveAsFlow()
.collect { itemId ->
screenModel.selectItemWithFeed(itemId)
?.let { openItem(it, preferences, navigator, context) }
}
}

LaunchedEffect(preferences.displayNotificationsPermission) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU
&& preferences.displayNotificationsPermission
Expand Down Expand Up @@ -504,4 +516,8 @@ object TimelineTab : Tab {
}
}
}

suspend fun openItem(itemId: Int) {
openItemChannel.send(itemId)
}
}
3 changes: 3 additions & 0 deletions db/src/main/java/com/readrops/db/dao/ItemDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ interface ItemDao : BaseDao<Item> {
@Query("Select * From Item Where id = :itemId")
suspend fun select(itemId: Int): Item

@Query("Select * From Item Limit 1")
suspend fun selectFirst(): Item

@RawQuery(observedEntities = [Item::class, Feed::class, Folder::class, ItemState::class])
fun selectAll(query: SupportSQLiteQuery): PagingSource<Int, ItemWithFeed>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ object ItemSelectionQueryBuilder {
"color",
"read_time",
"Feed.name",
"Feed.open_in",
"Feed.id as feedId",
"siteUrl",
"Folder.id as folder_id",
Expand Down

0 comments on commit a112e29

Please sign in to comment.