Browse Source

fix: refactor available feed trigger fix: handle twitter error

pull/9579/head
DarkPhoenix2704 2 months ago
parent
commit
a8dc019444
  1. 48
      packages/nc-gui/components/dashboard/Sidebar/Feed.vue
  2. 9
      packages/nc-gui/components/feed/Error.vue
  3. 8
      packages/nc-gui/components/feed/Recents/index.vue
  4. 39
      packages/nc-gui/components/feed/Twitter.vue
  5. 47
      packages/nc-gui/composables/useProductFeed.ts

48
packages/nc-gui/components/dashboard/Sidebar/Feed.vue

@ -1,55 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import dayjs from 'dayjs'
const workspaceStore = useWorkspace() const workspaceStore = useWorkspace()
const { navigateToFeed } = workspaceStore const { navigateToFeed } = workspaceStore
const { isFeedPageOpened } = storeToRefs(workspaceStore) const { isFeedPageOpened } = storeToRefs(workspaceStore)
const { appInfo } = useGlobal() const { isNewFeedAvailable } = useProductFeed()
const { loadFeed, socialFeed } = useProductFeed()
const isNewFeedAvailable = ref(false)
const checkNewFeed = async () => {
try {
await loadFeed({ type: 'all', loadMore: false })
if (!socialFeed.value.length) return
const [latestFeed] = socialFeed.value
const lastFeedTime = localStorage.getItem('lastFeedPublishedTime')
const lastFeed = dayjs(lastFeedTime)
if (!lastFeed.isValid() || dayjs(latestFeed['Published Time']).isAfter(lastFeed)) {
isNewFeedAvailable.value = true
localStorage.setItem('lastFeedPublishedTime', latestFeed['Published Time'])
}
} catch (error) {
console.error('Error while checking new feed', error)
}
}
const intervalId = ref()
const checkFeedWithInterval = async () => {
await checkNewFeed()
intervalId.value = setTimeout(checkFeedWithInterval, 3 * 60 * 60 * 1000)
}
onMounted(() => {
if (appInfo.value.feedEnabled) {
checkFeedWithInterval()
}
})
onUnmounted(() => {
if (intervalId.value) {
clearTimeout(intervalId.value)
intervalId.value = null
}
})
const gotoFeed = () => navigateToFeed() const gotoFeed = () => navigateToFeed()
</script> </script>
@ -60,7 +16,7 @@ const gotoFeed = () => navigateToFeed()
type="text" type="text"
full-width full-width
size="xsmall" size="xsmall"
class="n!xs:hidden my-0.5 !h-7 w-full !rounded-md !font-normal !px-3" class="n!xs:hidden my-0.5 w-full !h-7 !rounded-md !font-normal !pl-4.5 !pr-5"
data-testid="nc-sidebar-product-feed" data-testid="nc-sidebar-product-feed"
:centered="false" :centered="false"
:class="{ :class="{

9
packages/nc-gui/components/feed/Error.vue

@ -1,11 +1,18 @@
<script setup lang="ts"> <script setup lang="ts">
const props = defineProps<{ const props = defineProps<{
page: 'all' | 'youtube' | 'github' page: 'all' | 'youtube' | 'github' | 'twitter'
}>() }>()
const emits = defineEmits(['reload'])
const { loadFeed, socialFeed, youtubeFeed, githubFeed } = useProductFeed() const { loadFeed, socialFeed, youtubeFeed, githubFeed } = useProductFeed()
const triggerReload = async () => { const triggerReload = async () => {
if (props.page === 'twitter') {
emits('reload')
return
}
const data = (await loadFeed({ const data = (await loadFeed({
type: props.page, type: props.page,
loadMore: false, loadMore: false,

8
packages/nc-gui/components/feed/Recents/index.vue

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
const { socialFeed, loadFeed, isErrorOccurred } = useProductFeed() const { socialFeed, loadFeed, isErrorOccurred, isNewFeedAvailable } = useProductFeed()
const scrollContainer = ref<HTMLElement>() const scrollContainer = ref<HTMLElement>()
@ -14,6 +14,12 @@ const { isLoading } = useInfiniteScroll(
}, },
{ distance: 1, interval: 2000 }, { distance: 1, interval: 2000 },
) )
onMounted(() => {
isNewFeedAvailable.value = false
const [latestFeed] = socialFeed.value
if (latestFeed) localStorage.setItem('lastFeedPublishedTime', latestFeed['Published Time'])
})
</script> </script>
<template> <template>

39
packages/nc-gui/components/feed/Twitter.vue

@ -1,17 +1,33 @@
<script setup lang="ts"> <script setup lang="ts">
const isLoaded = ref(false)
const scriptTag = ref() const scriptTag = ref()
const timelineStatus = reactive({
isLoaded: false,
isError: false,
})
const handleIframeLoad = () => { const handleIframeLoad = () => {
setTimeout(() => { setTimeout(() => {
isLoaded.value = true timelineStatus.isLoaded = true
}, 2000) }, 2000)
} }
const triggerReload = () => {
timelineStatus.isLoaded = false
timelineStatus.isError = false
nextTick(() => {
scriptTag.value.src = 'https://platform.twitter.com/widgets.js'
})
}
onMounted(() => { onMounted(() => {
scriptTag.value.src = 'https://platform.twitter.com/widgets.js' scriptTag.value.src = 'https://platform.twitter.com/widgets.js'
}) })
const handleError = () => {
timelineStatus.isLoaded = true
timelineStatus.isError = true
}
</script> </script>
<template> <template>
@ -22,13 +38,24 @@ onMounted(() => {
}" }"
class="overflow-y-auto nc-scrollbar-md w-full" class="overflow-y-auto nc-scrollbar-md w-full"
> >
<div v-if="!isLoaded" class="flex items-center justify-center h-full w-full"> <div v-if="!timelineStatus.isLoaded" class="flex items-center justify-center h-full w-full">
<GeneralLoader size="xlarge" /> <GeneralLoader size="xlarge" />
</div> </div>
<div v-else-if="timelineStatus.isError" class="h-full flex justify-center items-center">
<FeedError page="twitter" @reload="triggerReload" />
</div>
<div class="mx-auto flex flex-col my-6 items-center"> <div class="mx-auto flex flex-col my-6 items-center">
<div style="min-width: 650px"> <div style="min-width: 650px">
<a class="twitter-timeline" href="https://twitter.com/nocodb?ref_src=twsrc%5Etfw"></a> <a data-chrome="nofooter" class="twitter-timeline" href="https://twitter.com/nocodb?ref_src=twsrc%5Etfw"></a>
<Script ref="scriptTag" async charset="utf-8" @load="handleIframeLoad"></Script> <Script
v-if="!timelineStatus.isError"
ref="scriptTag"
async
charset="utf-8"
@load="handleIframeLoad"
@error="handleError"
></Script>
</div> </div>
</div> </div>
</div> </div>

47
packages/nc-gui/composables/useProductFeed.ts

@ -1,3 +1,4 @@
import dayjs from 'dayjs'
import type { ProductFeedItem } from '../lib/types' import type { ProductFeedItem } from '../lib/types'
export const useProductFeed = createSharedComposable(() => { export const useProductFeed = createSharedComposable(() => {
@ -5,6 +6,8 @@ export const useProductFeed = createSharedComposable(() => {
const { $api } = useNuxtApp() const { $api } = useNuxtApp()
const { appInfo } = useGlobal()
const youtubeFeed = ref<ProductFeedItem[]>([]) const youtubeFeed = ref<ProductFeedItem[]>([])
const githubFeed = ref<ProductFeedItem[]>([]) const githubFeed = ref<ProductFeedItem[]>([])
@ -37,10 +40,6 @@ export const useProductFeed = createSharedComposable(() => {
const response = await $api.utils.feed({ page, per_page: 10, type }) const response = await $api.utils.feed({ page, per_page: 10, type })
if (type === 'all' && page === 1 && response.length) {
localStorage.setItem('last_published_at', response[0]['Published Time'] as string)
}
switch (type) { switch (type) {
case 'youtube': case 'youtube':
youtubeFeed.value = [...youtubeFeed.value, ...response] as ProductFeedItem[] youtubeFeed.value = [...youtubeFeed.value, ...response] as ProductFeedItem[]
@ -69,6 +68,45 @@ export const useProductFeed = createSharedComposable(() => {
} }
} }
const isNewFeedAvailable = ref(false)
const checkNewFeed = async () => {
try {
await loadFeed({ type: 'all', loadMore: false })
if (!socialFeed.value.length) return
const [latestFeed] = socialFeed.value
const lastFeedTime = localStorage.getItem('lastFeedPublishedTime')
const lastFeed = dayjs(lastFeedTime)
if (!lastFeed.isValid() || dayjs(latestFeed['Published Time']).isAfter(lastFeed)) {
isNewFeedAvailable.value = true
}
} catch (error) {
console.error('Error while checking new feed', error)
}
}
const intervalId = ref()
const checkFeedWithInterval = async () => {
await checkNewFeed()
intervalId.value = setTimeout(checkFeedWithInterval, 3 * 60 * 60 * 1000)
}
onMounted(() => {
if (appInfo.value.feedEnabled) {
checkFeedWithInterval()
}
})
onUnmounted(() => {
if (intervalId.value) {
clearTimeout(intervalId.value)
intervalId.value = null
}
})
return { return {
isErrorOccurred, isErrorOccurred,
activeTab, activeTab,
@ -76,5 +114,6 @@ export const useProductFeed = createSharedComposable(() => {
githubFeed, githubFeed,
socialFeed, socialFeed,
loadFeed, loadFeed,
isNewFeedAvailable,
} }
}) })

Loading…
Cancel
Save