Skip to content

Commit

Permalink
Merge pull request #116 from FreeNowOrg/dev
Browse files Browse the repository at this point in the history
feat: + site notice
  • Loading branch information
AlPha5130 authored Apr 26, 2024
2 parents e6b4df6 + c797d0a commit c2fb475
Show file tree
Hide file tree
Showing 8 changed files with 148 additions and 15 deletions.
43 changes: 33 additions & 10 deletions api/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,24 +97,47 @@ ajax.interceptors.response.use((ctx) => {
export function replacePximgUrlsInString(str: string): string {
if (!str.includes('pximg.net')) return str
return str
.replace(/https:\/\/i\.pximg\.net\//g, PXIMG_BASEURL_I)
.replace(/https:\/\/s\.pximg\.net\//g, PXIMG_BASEURL_S)
.replaceAll('https://i.pximg.net/', PXIMG_BASEURL_I)
.replaceAll('https://s.pximg.net/', PXIMG_BASEURL_S)
}

export function replacePximgUrlsInObject(
obj: Record<string, any> | string
): Record<string, any> | string {
if (typeof obj === 'string') return replacePximgUrlsInString(obj)
if (['arraybuffer', 'blob'].includes(obj.constructor.name.toLowerCase())) {
return obj
}

return JSON.parse(safelyStringify(obj), (key: string, val: any) => {
if (typeof val === 'string' && val.includes('pximg.net')) {
return replacePximgUrlsInString(val)
return deepReplaceString(obj, replacePximgUrlsInString)
}

function isObject(value: any): value is Record<string, any> {
return typeof value === 'object' && value !== null
}

export function deepReplaceString<T>(
obj: T,
replacer: (value: string) => string
): T {
if (Array.isArray(obj)) {
return obj.map((value) =>
deepReplaceString(value, replacer)
) as unknown as T
} else if (isObject(obj)) {
if (
['arraybuffer', 'blob', 'formdata'].includes(
obj.constructor.name.toLowerCase()
)
) {
return obj
}
return val
})
const result: Record<string, any> = {}
for (const [key, value] of Object.entries(obj)) {
result[key] = deepReplaceString(value, replacer)
}
return result as T
} else if (typeof obj === 'string') {
return replacer(obj) as unknown as T
}
return obj
}

export function safelyStringify(value: any, space?: number) {
Expand Down
8 changes: 6 additions & 2 deletions components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,21 @@ declare module 'vue' {
LazyLoad: typeof import('./src/components/LazyLoad.vue')['default']
ListLink: typeof import('./src/components/SideNav/ListLink.vue')['default']
NaiveuiProvider: typeof import('./src/components/NaiveuiProvider.vue')['default']
NAlert: typeof import('naive-ui')['NAlert']
NButton: typeof import('naive-ui')['NButton']
NCard: typeof import('naive-ui')['NCard']
NCountdown: typeof import('naive-ui')['NCountdown']
NEmpty: typeof import('naive-ui')['NEmpty']
NFlex: typeof import('naive-ui')['NFlex']
NLi: typeof import('naive-ui')['NLi']
NPagination: typeof import('naive-ui')['NPagination']
NPaginator: typeof import('naive-ui')['NPaginator']
NProgress: typeof import('./src/components/NProgress.vue')['default']
NSpace: typeof import('naive-ui')['NSpace']
NStatistic: typeof import('naive-ui')['NStatistic']
NTabPane: typeof import('naive-ui')['NTabPane']
NTabs: typeof import('naive-ui')['NTabs']
NTabsPane: typeof import('naive-ui')['NTabsPane']
NTag: typeof import('naive-ui')['NTag']
NUl: typeof import('naive-ui')['NUl']
Placeholder: typeof import('./src/components/Placeholder.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
Expand All @@ -45,6 +48,7 @@ declare module 'vue' {
SideNav: typeof import('./src/components/SideNav/SideNav.vue')['default']
SiteFooter: typeof import('./src/components/SiteFooter.vue')['default']
SiteHeader: typeof import('./src/components/SiteHeader.vue')['default']
SiteNoticeBanner: typeof import('./src/components/SiteNoticeBanner.vue')['default']
UgoiraViewer: typeof import('./src/components/UgoiraViewer.vue')['default']
}
}
6 changes: 4 additions & 2 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
<template lang="pug">
NaiveuiProvider#app-full-container
SiteNoticeBanner
SiteHeader

main
article
RouterView

SideNav
SiteHeader
SiteFooter
NProgress
</template>
Expand Down Expand Up @@ -51,7 +53,7 @@ onMounted(async () => {
flex-direction: column
main
padding-top: 50px
// padding-top: 50px
position: relative
flex: 1
article
Expand Down
2 changes: 1 addition & 1 deletion src/components/SiteHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ onMounted(() => {
color: var(--theme-background-color)
display: flex
align-items: center
position: fixed
position: sticky
height: 50px
width: 100%
box-sizing: border-box
Expand Down
52 changes: 52 additions & 0 deletions src/components/SiteNoticeBanner.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<template lang="pug">
Transition(name='fade')
#sitenotice-banner(v-if='isShow')
NAlert(
@close='handleClose'
closable
style='font-size: 1.5rem'
title='全站公告'
type='warning'
)
NUl
NLi: RouterLink(to='/notifications/2024-04-26') 关于 PixivNow 将可能停止服务的通知(2024年4月26日)
</template>

<script setup lang="ts">
import {} from 'vue'
const alreadyShown = ref(false)
const forceShow = computed(
() =>
route.name === 'about-us' || Date.now() > new Date('2024-09-01').getTime()
)
const isShow = computed(() => {
if (route.path === '/notifications/2024-04-26') {
return false
}
if (forceShow.value) return true
return !alreadyShown.value
})
const key = `pixivnow:sitenotice/2024-04-26`
const route = useRoute()
onMounted(() => {
alreadyShown.value = !!localStorage.getItem(key)
})
function handleClose() {
localStorage.setItem(key, '1')
alreadyShown.value = 1
}
</script>

<style scoped lang="sass">
.fade-enter-active,
.fade-leave-active
transition: all 0.5s ease-in-out
.fade-enter-from,
.fade-leave-to
opacity: 0
height: 0
</style>
5 changes: 5 additions & 0 deletions src/plugins/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ const routes: RouteRecordRaw[] = [
name: 'about-us',
component: () => import('@/view/about.vue'),
},
{
path: '/notifications/2024-04-26',
name: 'notification-2024-04-26',
component: () => import('@/view/notifications/2024-04-26.vue'),
},
{
path: '/:pathMatch(.*)*',
name: 'not-found',
Expand Down
46 changes: 46 additions & 0 deletions src/view/notifications/2024-04-26.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<template lang="pug">
#notification-view.body-inner
h1.align-center 关于 PixivNow 将可能停止服务的通知(2024年4月26日)
Card
p 各位,早上好中午好晚上好:
p 我们希望通知您,由于 Vercel 在 2024年4月4日 对其<a href="https://vercel.com/blog/improved-infrastructure-pricing" target="_blank">定价策略</a>进行了修改,细化了收费指标,这对我们的项目产生了重大影响。特别是,我们的项目在部分指标上的用量<strong>已经远超过了</strong>免费计划的限额。由于 PixivNow 是一个开源项目,并且到目前为止我们<strong>没有任何盈利</strong>,我们很难为了这个兴趣使然的项目自掏腰包。
p 幸运的是,Vercel 为现有的免费计划用户提供了 6 个月的缓冲期,这意味着我们的服务在接下来的六个月内不会受到影响。但是在此之后(大约是 2024年9月),我们的服务有极大概率将被迫中断。
p 在接下来的几个月里,我们将探索所有可能的解决方案以继续提供服务(前提是尽量不要花钱)。
p 我们非常感谢您一直以来对 PixivNow 的支持和理解。如果您希望继续支持我们,我们正在考虑接受赞助来帮助维持项目的运行。您可以通过访问我们的赞助页面了解更多信息,并考虑成为我们的赞助者。

.flex(style='justify-content: center')
NStatistic(
label='死亡倒计时'
style='border: 1px solid #efefef; padding: 0.5rem; border-radius: 0.25rem'
)
NCountdown(:duration='duration')

div(style='text-align: right')
strong Dragon Fish
br
time 2024年4月26日

Card(title='赞助我们')
.align-center
iframe(
frameborder='0'
height='200'
scrolling='no'
src='https://afdian.net/leaflet?slug=dragon-fish'
width='640'
)

Card(title='联系我们')
ul
li QQ群:1026023666
</template>

<script setup lang="ts">
import {} from 'vue'
const fromTime = new Date()
const toTime = new Date('2024-09-30T23:59:59Z')
const duration = toTime.getTime() - fromTime.getTime()
</script>

<style scoped lang="sass"></style>
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"types": ["unplugin-icons/types/vue"]
},
"include": [
"api/**/*.ts",
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.tsx",
Expand Down

0 comments on commit c2fb475

Please sign in to comment.