Merge pull request #2485 from omnivore-app/fix/save-url-timezone

fix/save url timezone and locale
This commit is contained in:
Hongbo Wu 2023-07-13 19:07:36 +08:00 committed by GitHub
commit 799eaaded4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 59 additions and 20 deletions

View file

@ -1720,6 +1720,8 @@ input SaveUrlInput {
source: String!
state: ArticleSavingRequestStatus
url: String!
timezone: String
locale: String
}
type SearchError {

View file

@ -3,6 +3,7 @@ package app.omnivore.omnivore.networking
import android.content.ContentValues
import android.net.Uri
import android.util.Log
import androidx.compose.ui.text.intl.Locale
import androidx.lifecycle.viewModelScope
import app.omnivore.omnivore.Constants
import app.omnivore.omnivore.graphql.generated.SaveUrlMutation
@ -17,7 +18,8 @@ import java.util.*
suspend fun Networker.deleteSavedItem(itemID: String): Boolean {
return try {
val input = SetBookmarkArticleInput(itemID, false)
val result = authenticatedApolloClient().mutation(SetBookmarkArticleMutation(input)).execute()
val result =
authenticatedApolloClient().mutation(SetBookmarkArticleMutation(input)).execute()
result.data?.setBookmarkArticle?.onSetBookmarkArticleSuccess?.bookmarkedArticle?.id != null
} catch (e: java.lang.Exception) {
false
@ -32,7 +34,10 @@ suspend fun Networker.unarchiveSavedItem(itemID: String): Boolean {
return updateArchiveStatusSavedItem(itemID, false)
}
suspend fun Networker.updateArchiveStatusSavedItem(itemID: String, setAsArchived: Boolean): Boolean {
suspend fun Networker.updateArchiveStatusSavedItem(
itemID: String,
setAsArchived: Boolean
): Boolean {
return try {
val input = ArchiveLinkInput(setAsArchived, itemID)
val result = authenticatedApolloClient().mutation(SetLinkArchivedMutation(input)).execute()
@ -45,7 +50,16 @@ suspend fun Networker.updateArchiveStatusSavedItem(itemID: String, setAsArchived
suspend fun Networker.saveUrl(url: Uri): Boolean {
return try {
val clientRequestId = UUID.randomUUID().toString()
val input = SaveUrlInput(url = url.toString(), clientRequestId = clientRequestId, source = "android")
// get locale and timezone from device
val timezone = TimeZone.getDefault().id
val locale = Locale.current.toLanguageTag()
val input = SaveUrlInput(
url = url.toString(),
clientRequestId = clientRequestId,
source = "android",
timezone = Optional.present(timezone),
locale = Optional.present(locale)
)
val result = authenticatedApolloClient().mutation(SaveUrlMutation(input)).execute()
result.data?.saveUrl?.onSaveSuccess?.url != null
} catch (e: java.lang.Exception) {

View file

@ -52,7 +52,7 @@ class SaveSheetActivity : SaveSheetActivityBase() {}
@AndroidEntryPoint
@OptIn(ExperimentalMaterialApi::class)
abstract class SaveSheetActivityBase: AppCompatActivity() {
abstract class SaveSheetActivityBase : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -74,6 +74,7 @@ abstract class SaveSheetActivityBase: AppCompatActivity() {
}
}
}
else -> {
// Handle other intents, such as being started from the home screen
}
@ -110,8 +111,11 @@ abstract class SaveSheetActivityBase: AppCompatActivity() {
.clip(RoundedCornerShape(topEnd = 5.dp, topStart = 5.dp)),
containerColor = MaterialTheme.colors.background,
actions = {
Spacer(modifier = Modifier.width(25.dp))
Text(message, style = androidx.compose.material3.MaterialTheme.typography.titleMedium)
Spacer(modifier = Modifier.width(25.dp))
Text(
message,
style = androidx.compose.material3.MaterialTheme.typography.titleMedium
)
},
)
},
@ -181,7 +185,7 @@ abstract class SaveSheetActivityBase: AppCompatActivity() {
) {
coroutineScope.launch {
if (withResults) setResult(RESULT_OK)
result?.let { intent = it}
result?.let { intent = it }
modalBottomSheetState.hide() // will trigger the LaunchedEffect
}
}
@ -191,9 +195,11 @@ abstract class SaveSheetActivityBase: AppCompatActivity() {
viewModel: SaveViewModel,
modalBottomSheetState: ModalBottomSheetState
) {
Box(modifier = Modifier
.height(300.dp)
.background(Color.White)) {
Box(
modifier = Modifier
.height(300.dp)
.background(Color.White)
) {
SaveContent(viewModel, modalBottomSheetState, modifier = Modifier.fillMaxSize())
}
}

View file

@ -5,6 +5,7 @@ import android.util.Log
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.text.intl.Locale
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
@ -14,6 +15,7 @@ import app.omnivore.omnivore.DatastoreRepository
import app.omnivore.omnivore.graphql.generated.SaveUrlMutation
import app.omnivore.omnivore.graphql.generated.type.SaveUrlInput
import com.apollographql.apollo3.ApolloClient
import com.apollographql.apollo3.api.Optional
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
@ -31,7 +33,7 @@ enum class SaveState {
@HiltViewModel
class SaveViewModel @Inject constructor(
private val datastoreRepo: DatastoreRepository
): ViewModel() {
) : ViewModel() {
val saveState = MutableLiveData(SaveState.NONE)
var isLoading by mutableStateOf(false)
@ -81,13 +83,18 @@ class SaveViewModel @Inject constructor(
try {
clientRequestID = UUID.randomUUID().toString()
// get locale and timezone from device
val timezone = TimeZone.getDefault().id
val locale = Locale.current.toLanguageTag()
val response = apolloClient.mutation(
SaveUrlMutation(
SaveUrlInput(
clientRequestId = clientRequestID!!,
source = "android",
url = cleanedUrl
url = cleanedUrl,
timezone = Optional.present(timezone),
locale = Optional.present(locale)
)
)
).execute()

View file

@ -1,5 +1,6 @@
import { useCallback, useState } from 'react'
import toast from 'react-hot-toast'
import { locale, timeZone } from '../../../lib/dateFormatting'
import { saveUrlMutation } from '../../../lib/networking/mutations/saveUrlMutation'
import { showErrorToast } from '../../../lib/toastHelpers'
import { Button } from '../../elements/Button'
@ -21,8 +22,8 @@ export function AddLinkModal(props: AddLinkModalProps): JSX.Element {
const [link, setLink] = useState('')
const handleLinkSubmission = useCallback(
async (link: string) => {
const result = await saveUrlMutation(link)
async (link: string, timezone: string, locale: string) => {
const result = await saveUrlMutation(link, timezone, locale)
if (result) {
toast(
() => (
@ -95,7 +96,7 @@ export function AddLinkModal(props: AddLinkModalProps): JSX.Element {
setLink(newLink)
submitLink = newLink
}
handleLinkSubmission(submitLink)
handleLinkSubmission(submitLink, timeZone, locale)
props.onOpenChange(false)
}}
>

View file

@ -1,8 +1,8 @@
//https://github.com/you-dont-need/You-Dont-Need-Momentjs
const locale = Intl.DateTimeFormat().resolvedOptions().locale || 'en-US'
export const locale = Intl.DateTimeFormat().resolvedOptions().locale || 'en-US'
// get the user's time zone
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone
export const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone
export function formattedLongDate(rawDate: string): string {
return new Intl.DateTimeFormat(locale, {

View file

@ -20,7 +20,9 @@ export type SaveUrlData = {
}
export async function saveUrlMutation(
url: string
url: string,
timezone?: string,
locale?: string
): Promise<SaveLinkOutput | undefined> {
const clientRequestId = uuidv4()
const mutation = gql`
@ -44,6 +46,8 @@ export async function saveUrlMutation(
url,
clientRequestId,
source: 'add-link',
timezone,
locale,
},
})
const output = data as SaveResponseData | undefined

View file

@ -1,5 +1,6 @@
import type { NextApiRequest, NextApiResponse } from 'next'
import { v4 as uuidv4 } from 'uuid'
import { locale, timeZone } from '../../lib/dateFormatting'
import { SaveResponseData } from '../../lib/networking/mutations/saveUrlMutation'
import { ssrFetcher } from '../../lib/networking/networkHelpers'
@ -7,7 +8,9 @@ const saveUrl = async (
req: NextApiRequest,
url: URL,
labels: string[] | undefined,
state: string | undefined
state: string | undefined,
timezone?: string,
locale?: string
) => {
const clientRequestId = uuidv4()
const mutation = `
@ -33,6 +36,8 @@ const saveUrl = async (
source: 'api-save-url',
labels: labels?.map((label) => ({ name: label })),
state,
timezone,
locale,
},
})
@ -60,7 +65,7 @@ export default async (
const labels = req.query['labels'] as string[] | undefined
const state = req.query['state'] as string | undefined
const url = new URL(urlStr as string)
const saveResult = await saveUrl(req, url, labels, state)
const saveResult = await saveUrl(req, url, labels, state, timeZone, locale)
console.log('saveResult: ', saveResult)
if (saveResult) {
res.redirect(`/article?url=${encodeURIComponent(url.toString())}`)