Skip to content

Commit

Permalink
feat: ogp cache を message ごとに分割してブラウザにキャッシュさせるように
Browse files Browse the repository at this point in the history
  • Loading branch information
cp-20 committed Dec 5, 2024
1 parent d7f5b20 commit be065b5
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 11 deletions.
3 changes: 2 additions & 1 deletion src/store/domain/messagesView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ const useMessagesViewPinia = defineStore('domain/messagesView', () => {
.map(async e => {
try {
await messagesStore.fetchOgpData({
url: e.url
url: e.url,
messageId
})
} catch {
// TODO: エラー処理、無効な埋め込みの扱いを考える必要あり
Expand Down
22 changes: 13 additions & 9 deletions src/store/entities/messages.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import type { FileInfo, Message, MessageStamp, Ogp } from '@traptitech/traq'
import type { AxiosError } from 'axios'
import mitt from 'mitt'
import { defineStore, acceptHMRUpdate } from 'pinia'
import { acceptHMRUpdate, defineStore } from 'pinia'
import { ref } from 'vue'
import apis from '/@/lib/apis'
import { createSingleflight } from '/@/lib/basic/async'
import { wsListener } from '/@/lib/websocket'
import { convertToRefsStore } from '/@/store/utils/convertToRefsStore'
import type { ExternalUrl, FileId, MessageId } from '/@/types/entity-ids'
import axios from 'axios'

type MessageEventMap = {
reconnect: void
Expand All @@ -21,7 +22,14 @@ export const messageMitt = mitt<MessageEventMap>()

const getMessage = createSingleflight(apis.getMessage.bind(apis))
const getFileMeta = createSingleflight(apis.getFileMeta.bind(apis))
const getOgp = createSingleflight(apis.getOgp.bind(apis))
// メッセージごとにネットワーク上 (ブラウザ上) のキャッシュを分けるために message=encodeURIComponent(messageId) を apis.getOgp に追加している
// (クエリパラメータを追加で渡せないので fetch で回避している)
const getOgp = createSingleflight((url: string, messageId: string) => {
const base = '/api/v3/ogp'
const urlEncoded = encodeURIComponent(url)
const messageIdEncoded = encodeURIComponent(messageId)
return axios.get(`${base}?url=${urlEncoded}&message=${messageIdEncoded}`)
})

const useMessagesStorePinia = defineStore('entities/messages', () => {
/**
Expand Down Expand Up @@ -101,18 +109,14 @@ const useMessagesStorePinia = defineStore('entities/messages', () => {
const ogpDataMap = ref(new Map<ExternalUrl, Ogp | undefined>())
const fetchOgpData = async ({
url,
ignoreCache = false
messageId
}: {
url: ExternalUrl
messageId: MessageId
ignoreCache?: boolean
}) => {
if (!ignoreCache && ogpDataMap.value.has(url)) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return ogpDataMap.value.get(url)!
}

try {
const [{ data: ogpData }, shared] = await getOgp(url)
const [{ data: ogpData }, shared] = await getOgp(url, messageId)
// ページにOGPが存在しない場合、undefinedを返す
if (ogpData.type === 'empty') {
if (!shared) ogpDataMap.value.set(url, undefined)
Expand Down
2 changes: 1 addition & 1 deletion src/views/Settings/ThemeTab.vue
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
<!-- eslint-enable vue/valid-v-model --->
<div>
<input
v-model="(val[name as keyof typeof val] as string)"
v-model="val[name as keyof typeof val] as string"
type="color"
:class="$style.colorInput"
/>
Expand Down

0 comments on commit be065b5

Please sign in to comment.