✨ (note) init image display
This commit is contained in:
@@ -17,11 +17,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent, nextTick, watch } from 'vue'
|
import { computed, defineComponent, nextTick, toRefs, watch } from 'vue'
|
||||||
import { useFile } from '@/hooks/useFile.hook'
|
import { useFile } from '@/hooks/useFile.hook'
|
||||||
import { useLinks } from '@/hooks/useLinks.hook'
|
import { useLinks } from '@/hooks/useLinks.hook'
|
||||||
import { useNoteOverlay } from '@/hooks/useNoteOverlay.hook'
|
import { useNoteOverlay } from '@/hooks/useNoteOverlay.hook'
|
||||||
import { useFocus } from '@/hooks/useFocus.hook'
|
import { useFocus } from '@/hooks/useFocus.hook'
|
||||||
|
import { useImages } from '@/hooks/useImages.hook'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'StackedNote',
|
name: 'StackedNote',
|
||||||
@@ -33,9 +34,10 @@ export default defineComponent({
|
|||||||
sha: { type: String, required: true }
|
sha: { type: String, required: true }
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
|
const refProps = toRefs(props)
|
||||||
|
const { scrollToFocusedNote } = useFocus()
|
||||||
const { content, fromCache } = useFile(props.user, props.repo, props.sha)
|
const { content, fromCache } = useFile(props.user, props.repo, props.sha)
|
||||||
const { listenToClick } = useLinks('stacked-note', props.sha)
|
const { listenToClick } = useLinks('stacked-note', props.sha)
|
||||||
const { scrollToFocusedNote } = useFocus()
|
|
||||||
const className = computed(() => `stacked-note-${props.index}`)
|
const className = computed(() => `stacked-note-${props.index}`)
|
||||||
const titleClassName = computed(() => `title-${className.value}`)
|
const titleClassName = computed(() => `title-${className.value}`)
|
||||||
|
|
||||||
@@ -45,6 +47,7 @@ export default defineComponent({
|
|||||||
if (content.value) {
|
if (content.value) {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
listenToClick()
|
listenToClick()
|
||||||
|
useImages(refProps.user, refProps.repo, props.sha)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -4,7 +4,12 @@ import { useGitHubLogin } from '@/hooks/useGitHubLogin.hook'
|
|||||||
import { Octokit } from '@octokit/rest'
|
import { Octokit } from '@octokit/rest'
|
||||||
import { useNoteCache } from '@/modules/note/hooks/useNoteCache'
|
import { useNoteCache } from '@/modules/note/hooks/useNoteCache'
|
||||||
|
|
||||||
export const useFile = (owner: string, repo: string, sha: string) => {
|
export const useFile = (
|
||||||
|
owner: string,
|
||||||
|
repo: string,
|
||||||
|
sha: string,
|
||||||
|
retrieveContent = true
|
||||||
|
) => {
|
||||||
const { getCachedNote, saveCacheNote } = useNoteCache(sha)
|
const { getCachedNote, saveCacheNote } = useNoteCache(sha)
|
||||||
const { accessToken } = useGitHubLogin()
|
const { accessToken } = useGitHubLogin()
|
||||||
const fromCache = ref(false)
|
const fromCache = ref(false)
|
||||||
@@ -15,17 +20,7 @@ export const useFile = (owner: string, repo: string, sha: string) => {
|
|||||||
|
|
||||||
const content = ref('')
|
const content = ref('')
|
||||||
|
|
||||||
const getContent = async () => {
|
const getFileContent = async () => {
|
||||||
const { render } = useMarkdown()
|
|
||||||
const cachedNote = await getCachedNote()
|
|
||||||
|
|
||||||
fromCache.value = !!cachedNote
|
|
||||||
|
|
||||||
if (cachedNote) {
|
|
||||||
content.value = render(cachedNote.content)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const file = await octokit.request(
|
const file = await octokit.request(
|
||||||
'GET /repos/{owner}/{repo}/git/blobs/{file_sha}',
|
'GET /repos/{owner}/{repo}/git/blobs/{file_sha}',
|
||||||
{
|
{
|
||||||
@@ -35,18 +30,36 @@ export const useFile = (owner: string, repo: string, sha: string) => {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!file) {
|
return file?.data.content
|
||||||
|
}
|
||||||
|
|
||||||
|
const getContent = async () => {
|
||||||
|
const { render } = useMarkdown()
|
||||||
|
const contentFile = await getFileContent()
|
||||||
|
|
||||||
|
const cachedNote = await getCachedNote()
|
||||||
|
|
||||||
|
fromCache.value = !!cachedNote
|
||||||
|
|
||||||
|
if (cachedNote) {
|
||||||
|
content.value = render(cachedNote.content)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
saveCacheNote(file.data.content)
|
if (!contentFile) {
|
||||||
content.value = render(file.data.content)
|
return
|
||||||
|
}
|
||||||
|
saveCacheNote(contentFile)
|
||||||
|
content.value = render(contentFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
getContent()
|
if (retrieveContent) {
|
||||||
|
getContent()
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
content,
|
content,
|
||||||
|
getFileContent,
|
||||||
fromCache
|
fromCache
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
49
src/hooks/useImages.hook.ts
Normal file
49
src/hooks/useImages.hook.ts
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import { useFile } from '@/hooks/useFile.hook'
|
||||||
|
import { useRepo } from '@/hooks/useRepo.hook'
|
||||||
|
import { resolvePath } from '@/modules/repo/services/resolvePath'
|
||||||
|
import { computed, Ref } from 'vue'
|
||||||
|
|
||||||
|
const SRC_PREFIX = 'data:image/png;base64,'
|
||||||
|
|
||||||
|
export const useImages = (
|
||||||
|
user: Ref<string>,
|
||||||
|
repo: Ref<string>,
|
||||||
|
sha: string
|
||||||
|
) => {
|
||||||
|
const { tree } = useRepo(user, repo, false)
|
||||||
|
|
||||||
|
const currentFilePath = computed(
|
||||||
|
() => tree.value.find((file) => file.sha === sha)?.path
|
||||||
|
)
|
||||||
|
|
||||||
|
const images = document.querySelectorAll(`.note-${sha} img`)
|
||||||
|
|
||||||
|
images.forEach(async (image) => {
|
||||||
|
if (currentFilePath.value) {
|
||||||
|
const src = image.getAttribute('src')
|
||||||
|
if (!src || src.startsWith(SRC_PREFIX)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const imageFilePath = resolvePath(
|
||||||
|
currentFilePath.value,
|
||||||
|
image.getAttribute('src') ?? ''
|
||||||
|
)
|
||||||
|
|
||||||
|
const imageFile = tree.value.find((file) => file.path === imageFilePath)
|
||||||
|
|
||||||
|
if (!imageFile?.sha) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const { getFileContent } = useFile(
|
||||||
|
user.value,
|
||||||
|
repo.value,
|
||||||
|
imageFile.sha,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
|
const fileContent = await getFileContent()
|
||||||
|
image.setAttribute('src', `${SRC_PREFIX} ${fileContent}`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
import MarkdownIt from 'markdown-it'
|
import MarkdownIt from 'markdown-it'
|
||||||
import markdownItClass from '@toycode/markdown-it-class'
|
import markdownItClass from '@toycode/markdown-it-class'
|
||||||
|
|
||||||
const md = new MarkdownIt().use(markdownItClass, {
|
const md = new MarkdownIt({
|
||||||
|
typographer: true,
|
||||||
|
quotes: ['«\xA0', '\xA0»', '‹\xA0', '\xA0›']
|
||||||
|
}).use(markdownItClass, {
|
||||||
h1: ['title', 'is-2'],
|
h1: ['title', 'is-2'],
|
||||||
h2: ['title', 'is-3'],
|
h2: ['title', 'is-3'],
|
||||||
h3: ['title', 'is-4'],
|
h3: ['title', 'is-4'],
|
||||||
|
|||||||
@@ -9,13 +9,16 @@ let initial = true
|
|||||||
export const useQueryStackedNotes = () => {
|
export const useQueryStackedNotes = () => {
|
||||||
const { query } = useRoute()
|
const { query } = useRoute()
|
||||||
|
|
||||||
const setStackedNotes = () => {
|
const initResetStackedNote = () =>
|
||||||
stackedNotes.value = (Array.isArray(query.stackedNotes)
|
(Array.isArray(query.stackedNotes)
|
||||||
? query.stackedNotes
|
? query.stackedNotes
|
||||||
: [query.stackedNotes]
|
: [query.stackedNotes]
|
||||||
)
|
)
|
||||||
.map((n) => n?.toString())
|
.map((n) => n?.toString())
|
||||||
.filter((n) => !!n) as string[]
|
.filter((n) => !!n) as string[]
|
||||||
|
|
||||||
|
const setStackedNotes = () => {
|
||||||
|
stackedNotes.value = initResetStackedNote()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (initial) {
|
if (initial) {
|
||||||
@@ -27,6 +30,6 @@ export const useQueryStackedNotes = () => {
|
|||||||
stackedNotes: readonly(stackedNotes),
|
stackedNotes: readonly(stackedNotes),
|
||||||
updateQueryStackedNotes: (newStackedNotes: string[]) =>
|
updateQueryStackedNotes: (newStackedNotes: string[]) =>
|
||||||
(stackedNotes.value = newStackedNotes),
|
(stackedNotes.value = newStackedNotes),
|
||||||
resetStackedNotes: () => (stackedNotes.value = [])
|
resetStackedNotes: () => initResetStackedNote()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Ref, onMounted, ref, watch } from '@vue/runtime-core'
|
import { Ref, ref, watch } from '@vue/runtime-core'
|
||||||
|
|
||||||
import { Octokit } from '@octokit/rest'
|
import { Octokit } from '@octokit/rest'
|
||||||
import { useGitHubLogin } from '@/hooks/useGitHubLogin.hook'
|
import { useGitHubLogin } from '@/hooks/useGitHubLogin.hook'
|
||||||
@@ -14,7 +14,13 @@ interface Tree {
|
|||||||
url?: string
|
url?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useRepo = (owner: Ref<string>, repo: Ref<string>) => {
|
const tree = ref<Tree[]>([])
|
||||||
|
|
||||||
|
export const useRepo = (
|
||||||
|
owner: Ref<string>,
|
||||||
|
repo: Ref<string>,
|
||||||
|
retrieve = true
|
||||||
|
) => {
|
||||||
const { getCachedNote, saveCacheNote } = useNoteCache('README')
|
const { getCachedNote, saveCacheNote } = useNoteCache('README')
|
||||||
const { accessToken } = useGitHubLogin()
|
const { accessToken } = useGitHubLogin()
|
||||||
const { render } = useMarkdown()
|
const { render } = useMarkdown()
|
||||||
@@ -25,7 +31,6 @@ export const useRepo = (owner: Ref<string>, repo: Ref<string>) => {
|
|||||||
|
|
||||||
const readme = ref<string | null>(null)
|
const readme = ref<string | null>(null)
|
||||||
const notFound = ref(false)
|
const notFound = ref(false)
|
||||||
const tree = ref<Tree[]>([])
|
|
||||||
|
|
||||||
const retrieveRepo = async () => {
|
const retrieveRepo = async () => {
|
||||||
if (!owner.value || !repo.value) {
|
if (!owner.value || !repo.value) {
|
||||||
@@ -82,9 +87,9 @@ export const useRepo = (owner: Ref<string>, repo: Ref<string>) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
if (retrieve) {
|
||||||
retrieveRepo()
|
retrieveRepo()
|
||||||
})
|
}
|
||||||
|
|
||||||
watch([owner, repo], () => retrieveRepo())
|
watch([owner, repo], () => retrieveRepo())
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,9 @@ export const useFolderNotes = (
|
|||||||
const { tree } = useRepo(owner, repo)
|
const { tree } = useRepo(owner, repo)
|
||||||
|
|
||||||
const fleetingNotes = computed(() =>
|
const fleetingNotes = computed(() =>
|
||||||
tree.value.filter((file) => file.path?.startsWith(folder))
|
tree.value.filter(
|
||||||
|
(file) => file.path?.startsWith(folder) && file.path?.endsWith('.md')
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
const content = computed(() =>
|
const content = computed(() =>
|
||||||
|
|||||||
Reference in New Issue
Block a user