♻️ (app)
This commit is contained in:
@@ -1,5 +1,8 @@
|
|||||||
require('@rushstack/eslint-patch/modern-module-resolution')
|
require('@rushstack/eslint-patch/modern-module-resolution')
|
||||||
|
|
||||||
|
const DEV_TOOL_ACTIVATED =
|
||||||
|
process.env.NODE_ENV === 'production' ? 'warn' : 'off'
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
root: true,
|
root: true,
|
||||||
env: {
|
env: {
|
||||||
@@ -11,13 +14,12 @@ module.exports = {
|
|||||||
'eslint:recommended',
|
'eslint:recommended',
|
||||||
'plugin:vue/recommended',
|
'plugin:vue/recommended',
|
||||||
'@vue/typescript/recommended',
|
'@vue/typescript/recommended',
|
||||||
'@vue/prettier',
|
|
||||||
'@vue/eslint-config-typescript',
|
'@vue/eslint-config-typescript',
|
||||||
'plugin:prettier-vue/recommended'
|
'plugin:prettier-vue/recommended'
|
||||||
],
|
],
|
||||||
rules: {
|
rules: {
|
||||||
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
'no-console': DEV_TOOL_ACTIVATED,
|
||||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
'no-debugger': DEV_TOOL_ACTIVATED,
|
||||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||||
'@typescript-eslint/camelcase': 'off',
|
'@typescript-eslint/camelcase': 'off',
|
||||||
'prettier-vue/prettier': [
|
'prettier-vue/prettier': [
|
||||||
@@ -29,7 +31,6 @@ module.exports = {
|
|||||||
arrowParens: 'always'
|
arrowParens: 'always'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
semi: 0,
|
|
||||||
'vue/no-v-html': 'off',
|
'vue/no-v-html': 'off',
|
||||||
'no-restricted-imports': [
|
'no-restricted-imports': [
|
||||||
'error',
|
'error',
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"semi": false,
|
|
||||||
"singleQuote": true,
|
|
||||||
"trailingComma": "none",
|
|
||||||
"arrowParens": "always"
|
|
||||||
}
|
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"serve": "vite preview",
|
"serve": "vite preview",
|
||||||
"test": "vitest",
|
"test": "vitest",
|
||||||
"lint": "eslint --ext .js,.vue --ignore-path .gitignore --fix src",
|
"lint": "eslint --ext .ts,.js,.vue --ignore-path .gitignore --fix src",
|
||||||
"pwa:asset": "npx vue-pwa-asset-generator -a public/img/logo.png --no-manifest"
|
"pwa:asset": "npx vue-pwa-asset-generator -a public/img/logo.png --no-manifest"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -52,7 +52,6 @@
|
|||||||
"@vue/eslint-config-typescript": "^11.0.3",
|
"@vue/eslint-config-typescript": "^11.0.3",
|
||||||
"eslint": "^8.46.0",
|
"eslint": "^8.46.0",
|
||||||
"eslint-config-prettier": "^9.0.0",
|
"eslint-config-prettier": "^9.0.0",
|
||||||
"eslint-plugin-prettier": "^5.0.0",
|
|
||||||
"eslint-plugin-prettier-vue": "^4.2.0",
|
"eslint-plugin-prettier-vue": "^4.2.0",
|
||||||
"eslint-plugin-vue": "^9.16.1",
|
"eslint-plugin-vue": "^9.16.1",
|
||||||
"prettier": "^3.0.1",
|
"prettier": "^3.0.1",
|
||||||
|
|||||||
6157
pnpm-lock.yaml
generated
6157
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,6 @@ import { useQueryStackedNotes } from '@/hooks/useQueryStackedNotes.hook'
|
|||||||
import { useVisitRepo } from '@/modules/history/hooks/useVisitRepo.hook'
|
import { useVisitRepo } from '@/modules/history/hooks/useVisitRepo.hook'
|
||||||
import { useUserRepoStore } from '@/modules/repo/store/userRepo.store'
|
import { useUserRepoStore } from '@/modules/repo/store/userRepo.store'
|
||||||
import { useUserSettings } from '@/modules/user/hooks/useUserSettings.hook'
|
import { useUserSettings } from '@/modules/user/hooks/useUserSettings.hook'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
computed,
|
computed,
|
||||||
defineAsyncComponent,
|
defineAsyncComponent,
|
||||||
@@ -43,11 +42,14 @@ const props = withDefaults(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const user = computed(() => props.user)
|
||||||
|
const repo = computed(() => props.repo)
|
||||||
|
|
||||||
const refProps = toRefs(props)
|
const refProps = toRefs(props)
|
||||||
const store = useUserRepoStore()
|
const store = useUserRepoStore()
|
||||||
useUserSettings()
|
useUserSettings()
|
||||||
const { visitRepo } = useVisitRepo({ user: props.user, repo: props.repo })
|
const { visitRepo } = useVisitRepo({ user: user, repo: repo })
|
||||||
const { toHTML } = useMarkdown(props.repo)
|
const { toHTML } = useMarkdown(repo)
|
||||||
const { listenToClick } = useLinks('note-display')
|
const { listenToClick } = useLinks('note-display')
|
||||||
const { stackedNotes, resetStackedNotes } = useQueryStackedNotes()
|
const { stackedNotes, resetStackedNotes } = useQueryStackedNotes()
|
||||||
const { scrollToFocusedNote } = useQueryStackedNotes()
|
const { scrollToFocusedNote } = useQueryStackedNotes()
|
||||||
@@ -104,7 +106,8 @@ const focus = () => scrollToFocusedNote(undefined, true)
|
|||||||
[<router-link
|
[<router-link
|
||||||
:to="{ name: 'FluxNoteView', params: { user, repo } }"
|
:to="{ name: 'FluxNoteView', params: { user, repo } }"
|
||||||
@click="resetStackedNotes"
|
@click="resetStackedNotes"
|
||||||
>{{ repo }}</router-link
|
>
|
||||||
|
{{ repo }} </router-link
|
||||||
>]
|
>]
|
||||||
<img
|
<img
|
||||||
v-if="store.isReadmeOffline"
|
v-if="store.isReadmeOffline"
|
||||||
@@ -123,7 +126,7 @@ const focus = () => scrollToFocusedNote(undefined, true)
|
|||||||
v-else-if="withContent"
|
v-else-if="withContent"
|
||||||
class="note-display"
|
class="note-display"
|
||||||
v-html="renderedContent"
|
v-html="renderedContent"
|
||||||
></p>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<stacked-note
|
<stacked-note
|
||||||
v-for="(stackedNote, index) in stackedNotes"
|
v-for="(stackedNote, index) in stackedNotes"
|
||||||
@@ -160,6 +163,7 @@ $header-height: 40px;
|
|||||||
table {
|
table {
|
||||||
color: var(--font-color);
|
color: var(--font-color);
|
||||||
background-color: var(--background-color);
|
background-color: var(--background-color);
|
||||||
|
|
||||||
thead {
|
thead {
|
||||||
th {
|
th {
|
||||||
color: var(--font-color);
|
color: var(--font-color);
|
||||||
|
|||||||
@@ -22,17 +22,22 @@ const props = defineProps<{
|
|||||||
sha: string
|
sha: string
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
const sha = computed(() => props.sha)
|
||||||
|
const index = computed(() => props.index)
|
||||||
|
const repo = computed(() => props.repo)
|
||||||
|
|
||||||
const { scrollToFocusedNote } = useQueryStackedNotes()
|
const { scrollToFocusedNote } = useQueryStackedNotes()
|
||||||
const { content } = useFile(props.sha)
|
|
||||||
|
const { content } = useFile(sha)
|
||||||
const className = computed(() => `stacked-note-${props.index}`)
|
const className = computed(() => `stacked-note-${props.index}`)
|
||||||
const { listenToClick } = useLinks(className.value, props.sha)
|
const { listenToClick } = useLinks(className.value, sha)
|
||||||
const titleClassName = computed(() => `title-${className.value}`)
|
const titleClassName = computed(() => `title-${className.value}`)
|
||||||
useTitleNotes(props.repo)
|
useTitleNotes(repo)
|
||||||
|
|
||||||
const store = useUserRepoStore()
|
const store = useUserRepoStore()
|
||||||
const hasBacklinks = computed(() => store.userSettings?.backlink)
|
const hasBacklinks = computed(() => store.userSettings?.backlink)
|
||||||
|
|
||||||
const { displayNoteOverlay } = useNoteOverlay(className.value, props.index)
|
const { displayNoteOverlay } = useNoteOverlay(className.value, index)
|
||||||
const displayedTitle = computed(() => filenameToNoteTitle(props.title))
|
const displayedTitle = computed(() => filenameToNoteTitle(props.title))
|
||||||
|
|
||||||
watch(content, () => {
|
watch(content, () => {
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ import { useMarkdown } from '@/hooks/useMarkdown.hook'
|
|||||||
import { prepareNoteCache } from '@/modules/note/cache/prepareNoteCache'
|
import { prepareNoteCache } from '@/modules/note/cache/prepareNoteCache'
|
||||||
import { getFileContent } from '@/modules/repo/services/repo'
|
import { getFileContent } from '@/modules/repo/services/repo'
|
||||||
import { useUserRepoStore } from '@/modules/repo/store/userRepo.store'
|
import { useUserRepoStore } from '@/modules/repo/store/userRepo.store'
|
||||||
import { ref } from 'vue'
|
import { Ref, ref, toValue } from 'vue'
|
||||||
|
|
||||||
export const useFile = (sha: string, retrieveContent = true) => {
|
export const useFile = (sha: Ref<string> | string, retrieveContent = true) => {
|
||||||
const { render } = useMarkdown(sha)
|
const { render } = useMarkdown(toValue(sha))
|
||||||
const store = useUserRepoStore()
|
const store = useUserRepoStore()
|
||||||
const { getCachedNote, saveCacheNote } = prepareNoteCache(sha)
|
const { getCachedNote, saveCacheNote } = prepareNoteCache(toValue(sha))
|
||||||
const fromCache = ref(false)
|
const fromCache = ref(false)
|
||||||
|
|
||||||
const content = ref('')
|
const content = ref('')
|
||||||
@@ -42,7 +42,11 @@ export const useFile = (sha: string, retrieveContent = true) => {
|
|||||||
return cachedNote.content
|
return cachedNote.content
|
||||||
}
|
}
|
||||||
|
|
||||||
const contentFile = await getFileContent(store.user, store.repo, sha)
|
const contentFile = await getFileContent(
|
||||||
|
store.user,
|
||||||
|
store.repo,
|
||||||
|
toValue(sha)
|
||||||
|
)
|
||||||
|
|
||||||
if (!contentFile) {
|
if (!contentFile) {
|
||||||
return null
|
return null
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { noteEventBus } from '@/bus/noteEventBus'
|
import { noteEventBus } from '@/bus/noteEventBus'
|
||||||
import { useUserRepoStore } from '@/modules/repo/store/userRepo.store'
|
import { useUserRepoStore } from '@/modules/repo/store/userRepo.store'
|
||||||
import { isExternalLink } from '@/utils/link'
|
import { isExternalLink } from '@/utils/link'
|
||||||
import { ComputedRef, onUnmounted, toValue } from 'vue'
|
import { ComputedRef, onUnmounted, Ref, toValue } from 'vue'
|
||||||
|
|
||||||
export const useLinks = (
|
export const useLinks = (
|
||||||
className: ComputedRef<string> | string,
|
className: ComputedRef<string> | string,
|
||||||
sha?: string
|
sha?: Ref<string> | string
|
||||||
) => {
|
) => {
|
||||||
const store = useUserRepoStore()
|
const store = useUserRepoStore()
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ export const useLinks = (
|
|||||||
|
|
||||||
noteEventBus.emit({
|
noteEventBus.emit({
|
||||||
path: href,
|
path: href,
|
||||||
currentNoteSHA: sha,
|
currentNoteSHA: toValue(sha),
|
||||||
user: store.user,
|
user: store.user,
|
||||||
repo: store.repo
|
repo: store.repo
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import markdownItCheckbox from 'markdown-it-checkbox'
|
|||||||
import markdownItFootnote from 'markdown-it-footnote'
|
import markdownItFootnote from 'markdown-it-footnote'
|
||||||
import markdownItIframe from 'markdown-it-iframe'
|
import markdownItIframe from 'markdown-it-iframe'
|
||||||
import markdownItLatex from 'markdown-it-latex'
|
import markdownItLatex from 'markdown-it-latex'
|
||||||
|
import { Ref, toValue } from 'vue'
|
||||||
|
|
||||||
const md = new MarkdownIt({
|
const md = new MarkdownIt({
|
||||||
typographer: true,
|
typographer: true,
|
||||||
@@ -37,13 +38,13 @@ const md = new MarkdownIt({
|
|||||||
height: 400
|
height: 400
|
||||||
})
|
})
|
||||||
|
|
||||||
export const useMarkdown = (defaultPrefix?: string) => {
|
export const useMarkdown = (defaultPrefix?: Ref<string> | string) => {
|
||||||
return {
|
return {
|
||||||
toHTML: (content: string) => (content ? md.render(content) : ''),
|
toHTML: (content: string) => (content ? md.render(content) : ''),
|
||||||
render: (content: string, prefix?: string) =>
|
render: (content: string, prefix?: string) =>
|
||||||
content
|
content
|
||||||
? md.render(decodeBase64ToUTF8(content), {
|
? md.render(decodeBase64ToUTF8(content), {
|
||||||
docId: defaultPrefix ?? prefix ?? ''
|
docId: defaultPrefix ? toValue(defaultPrefix) : prefix ?? ''
|
||||||
})
|
})
|
||||||
: ''
|
: ''
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
import { computed, onMounted, onUnmounted, watch } from 'vue'
|
|
||||||
|
|
||||||
import { NOTE_WIDTH } from '@/constants/note-width'
|
|
||||||
import { noteEventBus } from '@/bus/noteEventBus'
|
import { noteEventBus } from '@/bus/noteEventBus'
|
||||||
|
import { NOTE_WIDTH } from '@/constants/note-width'
|
||||||
import { useOverlay } from '@/hooks/useOverlay.hook'
|
import { useOverlay } from '@/hooks/useOverlay.hook'
|
||||||
import { useQueryStackedNotes } from '@/hooks/useQueryStackedNotes.hook'
|
import { useQueryStackedNotes } from '@/hooks/useQueryStackedNotes.hook'
|
||||||
import { resolvePath } from '@/modules/repo/services/resolvePath'
|
import { resolvePath } from '@/modules/repo/services/resolvePath'
|
||||||
import { useUserRepoStore } from '@/modules/repo/store/userRepo.store'
|
import { useUserRepoStore } from '@/modules/repo/store/userRepo.store'
|
||||||
import { pathToNotePathTitle } from '@/utils/noteTitle'
|
import { pathToNotePathTitle } from '@/utils/noteTitle'
|
||||||
|
import { computed, onMounted, onUnmounted, watch } from 'vue'
|
||||||
|
|
||||||
export const useNote = (containerClass: string) => {
|
export const useNote = (containerClass: string) => {
|
||||||
const store = useUserRepoStore()
|
const store = useUserRepoStore()
|
||||||
|
|||||||
@@ -1,20 +1,22 @@
|
|||||||
import { computed, onMounted, ref } from 'vue'
|
|
||||||
|
|
||||||
import { NOTE_WIDTH } from '@/constants/note-width'
|
import { NOTE_WIDTH } from '@/constants/note-width'
|
||||||
import { useOverlay } from '@/hooks/useOverlay.hook'
|
import { useOverlay } from '@/hooks/useOverlay.hook'
|
||||||
import { useQueryStackedNotes } from '@/hooks/useQueryStackedNotes.hook'
|
import { useQueryStackedNotes } from '@/hooks/useQueryStackedNotes.hook'
|
||||||
|
import { computed, onMounted, Ref, ref, toValue } from 'vue'
|
||||||
|
|
||||||
const BOOKMARK_WIDTH = 2
|
const BOOKMARK_WIDTH = 2
|
||||||
|
|
||||||
export const useNoteOverlay = (className: string, index: number) => {
|
export const useNoteOverlay = (
|
||||||
|
className: string,
|
||||||
|
index: Ref<number> | number
|
||||||
|
) => {
|
||||||
const { x, y, isMobile } = useOverlay()
|
const { x, y, isMobile } = useOverlay()
|
||||||
const noteHeight = ref(0)
|
const noteHeight = ref(0)
|
||||||
|
|
||||||
const displayNoteOverlay = computed(() => {
|
const displayNoteOverlay = computed(() => {
|
||||||
if (isMobile.value) {
|
if (isMobile.value) {
|
||||||
return y.value > index * noteHeight.value
|
return y.value > toValue(index) * noteHeight.value
|
||||||
} else {
|
} else {
|
||||||
return x.value > index * NOTE_WIDTH
|
return x.value > toValue(index) * NOTE_WIDTH
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -32,7 +34,7 @@ export const useNoteOverlay = (className: string, index: number) => {
|
|||||||
if (isMobile.value) {
|
if (isMobile.value) {
|
||||||
noteElement.style.top = `0`
|
noteElement.style.top = `0`
|
||||||
} else {
|
} else {
|
||||||
noteElement.style.left = `${(index + 1) * BOOKMARK_WIDTH}rem`
|
noteElement.style.left = `${(toValue(index) + 1) * BOOKMARK_WIDTH}rem`
|
||||||
|
|
||||||
const stackedNoteContainers = document.querySelectorAll(
|
const stackedNoteContainers = document.querySelectorAll(
|
||||||
'.stacked-note'
|
'.stacked-note'
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ import { useQueryStackedNotes } from '@/hooks/useQueryStackedNotes.hook'
|
|||||||
import { useNotes } from '@/modules/note/hooks/useNotes'
|
import { useNotes } from '@/modules/note/hooks/useNotes'
|
||||||
import { pathToNoteTitle } from '@/utils/noteTitle'
|
import { pathToNoteTitle } from '@/utils/noteTitle'
|
||||||
import { useTitle } from '@vueuse/core'
|
import { useTitle } from '@vueuse/core'
|
||||||
import { computed, watch } from 'vue'
|
import { computed, Ref, toValue, watch } from 'vue'
|
||||||
|
|
||||||
export const generateTitle = (titles: string[]) => titles.join(' | ')
|
export const generateTitle = (titles: string[]) => titles.join(' | ')
|
||||||
|
|
||||||
export const useTitleNotes = (prefix: string) => {
|
export const useTitleNotes = (prefix: Ref<string> | string) => {
|
||||||
const { stackedNotes } = useQueryStackedNotes()
|
const { stackedNotes } = useQueryStackedNotes()
|
||||||
const { notes } = useNotes()
|
const { notes } = useNotes()
|
||||||
const titleNotes = computed(() =>
|
const titleNotes = computed(() =>
|
||||||
@@ -15,9 +15,9 @@ export const useTitleNotes = (prefix: string) => {
|
|||||||
.map((note) => pathToNoteTitle(note.path ?? ''))
|
.map((note) => pathToNoteTitle(note.path ?? ''))
|
||||||
)
|
)
|
||||||
|
|
||||||
const title = useTitle(generateTitle([prefix, ...titleNotes.value]))
|
const title = useTitle(generateTitle([toValue(prefix), ...titleNotes.value]))
|
||||||
|
|
||||||
watch(titleNotes, () => {
|
watch(titleNotes, () => {
|
||||||
title.value = generateTitle([prefix, ...titleNotes.value])
|
title.value = generateTitle([toValue(prefix), ...titleNotes.value])
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script lang="ts" setup>
|
||||||
import FlipCard from '@/modules/card/components/FlipCard.vue'
|
import FlipCard from '@/modules/card/components/FlipCard.vue'
|
||||||
import { Repetition } from '@/modules/card/hooks/useSpacedRepetitionCards'
|
import { Repetition } from '@/modules/card/hooks/useSpacedRepetitionCards'
|
||||||
import { ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
|
|
||||||
const props = defineProps<{ cards: Repetition[] }>()
|
const props = defineProps<{ cards: Repetition[] }>()
|
||||||
const emits = defineEmits<{
|
const emits = defineEmits<{
|
||||||
@@ -10,8 +10,10 @@ const emits = defineEmits<{
|
|||||||
needsReview: [id: string]
|
needsReview: [id: string]
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const cards = ref(
|
const propCards = computed(() => props.cards)
|
||||||
[...props.cards].sort((a, b) =>
|
|
||||||
|
const sortedCards = ref(
|
||||||
|
[...propCards.value].sort((a, b) =>
|
||||||
a.repetition.level > b.repetition.level ? -1 : 1
|
a.repetition.level > b.repetition.level ? -1 : 1
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -19,14 +21,14 @@ const cards = ref(
|
|||||||
const currentIndex = ref(0)
|
const currentIndex = ref(0)
|
||||||
|
|
||||||
const goToNextCard = (success: boolean) => {
|
const goToNextCard = (success: boolean) => {
|
||||||
const id = cards.value[currentIndex.value].repetition._id ?? ''
|
const id = sortedCards.value[currentIndex.value].repetition._id ?? ''
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
emits('success', id)
|
emits('success', id)
|
||||||
} else {
|
} else {
|
||||||
const failedCard = cards.value.at(currentIndex.value)
|
const failedCard = sortedCards.value.at(currentIndex.value)
|
||||||
if (failedCard) {
|
if (failedCard) {
|
||||||
cards.value.push(failedCard)
|
sortedCards.value.push(failedCard)
|
||||||
}
|
}
|
||||||
emits('fail', id)
|
emits('fail', id)
|
||||||
}
|
}
|
||||||
@@ -35,7 +37,7 @@ const goToNextCard = (success: boolean) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const needsReview = () => {
|
const needsReview = () => {
|
||||||
const id = cards.value[currentIndex.value].repetition._id ?? ''
|
const id = sortedCards.value[currentIndex.value].repetition._id ?? ''
|
||||||
emits('needsReview', id)
|
emits('needsReview', id)
|
||||||
currentIndex.value++
|
currentIndex.value++
|
||||||
}
|
}
|
||||||
@@ -44,13 +46,13 @@ const needsReview = () => {
|
|||||||
<template>
|
<template>
|
||||||
<div class="flip-card-list">
|
<div class="flip-card-list">
|
||||||
<h3 class="subtitle is-3">
|
<h3 class="subtitle is-3">
|
||||||
Level: {{ cards[currentIndex].repetition.level }}
|
Level: {{ sortedCards[currentIndex].repetition.level }}
|
||||||
</h3>
|
</h3>
|
||||||
<h4>cards left: {{ cards.length - currentIndex }}</h4>
|
<h4>cards left: {{ sortedCards.length - currentIndex }}</h4>
|
||||||
|
|
||||||
<div v-if="currentIndex < cards.length">
|
<div v-if="currentIndex < sortedCards.length">
|
||||||
<flip-card
|
<flip-card
|
||||||
v-for="(card, index) in cards"
|
v-for="(card, index) in sortedCards"
|
||||||
:key="card.repetition._id ?? ''"
|
:key="card.repetition._id ?? ''"
|
||||||
class="card"
|
class="card"
|
||||||
:style="{
|
:style="{
|
||||||
|
|||||||
@@ -10,7 +10,10 @@
|
|||||||
<router-link
|
<router-link
|
||||||
:to="{
|
:to="{
|
||||||
name: `FluxNoteView`,
|
name: `FluxNoteView`,
|
||||||
params: { user: lastVisitedRepo.user, repo: lastVisitedRepo.repo }
|
params: {
|
||||||
|
user: lastVisitedRepo.user,
|
||||||
|
repo: lastVisitedRepo.repo
|
||||||
|
}
|
||||||
}"
|
}"
|
||||||
>{{ lastVisitedRepo.user }}/{{ lastVisitedRepo.repo }}</router-link
|
>{{ lastVisitedRepo.user }}/{{ lastVisitedRepo.repo }}</router-link
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,18 +1,22 @@
|
|||||||
import { data } from '@/data/data'
|
import { data } from '@/data/data'
|
||||||
import { DataType } from '@/data/DataType.enum'
|
import { DataType } from '@/data/DataType.enum'
|
||||||
import { History } from '@/data/models/History'
|
import { History } from '@/data/models/History'
|
||||||
|
import { Ref, toValue } from 'vue'
|
||||||
|
|
||||||
const HISTORY_ID = data.generateId(DataType.History, 'history')
|
const HISTORY_ID = data.generateId(DataType.History, 'history')
|
||||||
const MAX_REPO_HISTORY = 10
|
const MAX_REPO_HISTORY = 10
|
||||||
|
|
||||||
export const useVisitRepo = (newRepo: { user: string; repo: string }) => {
|
export const useVisitRepo = (newRepo: {
|
||||||
|
user: Ref<string> | string
|
||||||
|
repo: Ref<string> | string
|
||||||
|
}) => {
|
||||||
const visitRepo = async () => {
|
const visitRepo = async () => {
|
||||||
const history = await data.get<DataType.History, History>(HISTORY_ID)
|
const history = await data.get<DataType.History, History>(HISTORY_ID)
|
||||||
if (!history) {
|
if (!history) {
|
||||||
const newHistory: History = {
|
const newHistory: History = {
|
||||||
_id: HISTORY_ID,
|
_id: HISTORY_ID,
|
||||||
$type: DataType.History,
|
$type: DataType.History,
|
||||||
repos: [newRepo]
|
repos: [{ user: toValue(newRepo.user), repo: toValue(newRepo.repo) }]
|
||||||
}
|
}
|
||||||
await data.add<DataType.History>(newHistory)
|
await data.add<DataType.History>(newHistory)
|
||||||
return
|
return
|
||||||
@@ -22,10 +26,10 @@ export const useVisitRepo = (newRepo: { user: string; repo: string }) => {
|
|||||||
(repo) => repo.user !== newRepo.user && repo.repo !== newRepo.repo
|
(repo) => repo.user !== newRepo.user && repo.repo !== newRepo.repo
|
||||||
)
|
)
|
||||||
|
|
||||||
const historyRepos = [newRepo, ...clearedRepos].slice(
|
const historyRepos = [
|
||||||
0,
|
{ user: toValue(newRepo.user), repo: toValue(newRepo.repo) },
|
||||||
MAX_REPO_HISTORY - 1
|
...clearedRepos
|
||||||
)
|
].slice(0, MAX_REPO_HISTORY - 1)
|
||||||
|
|
||||||
const newHistory: History = {
|
const newHistory: History = {
|
||||||
...history,
|
...history,
|
||||||
|
|||||||
1
src/shims-vue.d.ts
vendored
1
src/shims-vue.d.ts
vendored
@@ -11,3 +11,4 @@ declare module 'markdown-it-footnote'
|
|||||||
declare module 'markdown-it-regexp'
|
declare module 'markdown-it-regexp'
|
||||||
declare module 'markdown-it-latex'
|
declare module 'markdown-it-latex'
|
||||||
declare module 'markdown-it-iframe'
|
declare module 'markdown-it-iframe'
|
||||||
|
declare module '@rushstack/eslint-patch/modern-module-resolution'
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
@charset "utf-8";
|
@charset "utf-8";
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Courier+Prime&family=Courgette&family=IBM+Plex+Serif&family=Kiwi+Maru&family=Maven+Pro&family=Noto+Sans+KR&family=Tajawal&family=Domine&family=Amiri&display=swap&family=Montagu+Slab&family=Gowun+Batang&family=Cormorant+Garamond&family=Forum');
|
@import url("https://fonts.googleapis.com/css2?family=Courier+Prime&family=Courgette&family=IBM+Plex+Serif&family=Kiwi+Maru&family=Maven+Pro&family=Noto+Sans+KR&family=Tajawal&family=Domine&family=Amiri&display=swap&family=Montagu+Slab&family=Gowun+Batang&family=Cormorant+Garamond&family=Forum");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
font-family: 'Courgette', cursive;
|
font-family: 'Courgette', cursive;
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
$primary: #2c3a47;
|
$primary: #2c3a47;
|
||||||
$link: #44b9a0;
|
$link: #44b9a0;
|
||||||
$light-link: lighten($link, 45%);
|
$light-link: lighten($link, 45%);
|
||||||
$family-primary: 'Courier Prime', monospace;
|
$family-primary: "Courier Prime", monospace;
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--primary-color: #{$primary};
|
--primary-color: #{$primary};
|
||||||
@@ -27,7 +27,7 @@ $family-primary: 'Courier Prime', monospace;
|
|||||||
--note-width: 620px;
|
--note-width: 620px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@import '../../node_modules/bulma/bulma.sass';
|
@import "../../node_modules/bulma/bulma.sass";
|
||||||
|
|
||||||
html {
|
html {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
@@ -42,7 +42,6 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 769px) {
|
@media screen and (min-width: 769px) {
|
||||||
|
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
@@ -75,7 +74,7 @@ a {
|
|||||||
&::after {
|
&::after {
|
||||||
margin-left: 0.2rem;
|
margin-left: 0.2rem;
|
||||||
vertical-align: text-top;
|
vertical-align: text-top;
|
||||||
content: url('assets/icons/external-link.svg');
|
content: url("assets/icons/external-link.svg");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -93,7 +92,6 @@ a {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media print {
|
@media print {
|
||||||
|
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ export const markdownItPlugin = (
|
|||||||
|
|
||||||
const regexp = RegExp('^' + regex.source, flags)
|
const regexp = RegExp('^' + regex.source, flags)
|
||||||
|
|
||||||
const parse = (state: any, silent: boolean) => {
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
const parse = (state: any, silent: boolean): boolean => {
|
||||||
const match = regexp.exec(state.src.slice(state.pos))
|
const match = regexp.exec(state.src.slice(state.pos))
|
||||||
|
|
||||||
if (!match) {
|
if (!match) {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { markdownItPlugin } from '@/utils/markdown/markdown-it-regexp'
|
|||||||
export const twitterPlugin = markdownItPlugin(
|
export const twitterPlugin = markdownItPlugin(
|
||||||
/@\[tweet]\((.*?)\)/g,
|
/@\[tweet]\((.*?)\)/g,
|
||||||
(matches: RegExpExecArray[]) => {
|
(matches: RegExpExecArray[]) => {
|
||||||
const [_, tweetId] = matches
|
const [, tweetId] = matches
|
||||||
|
|
||||||
return `<span id="tweet-${tweetId}" data-tweet-id="${tweetId}" class="markdown-tweet"></span>`
|
return `<span id="tweet-${tweetId}" data-tweet-id="${tweetId}" class="markdown-tweet"></span>`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
window.twttr = (function (d, s, id) {
|
window.twttr = (function (d, s, id) {
|
||||||
let js,
|
const fjs = d.getElementsByTagName(s)[0],
|
||||||
fjs = d.getElementsByTagName(s)[0],
|
|
||||||
t = window.twttr || {}
|
t = window.twttr || {}
|
||||||
|
|
||||||
if (d.getElementById(id)) {
|
if (d.getElementById(id)) {
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
js = d.createElement(s)
|
const js = d.createElement(s)
|
||||||
js.id = id
|
js.id = id
|
||||||
js.src = 'https://platform.twitter.com/widgets.js'
|
js.src = 'https://platform.twitter.com/widgets.js'
|
||||||
fjs.parentNode.insertBefore(js, fjs)
|
fjs.parentNode.insertBefore(js, fjs)
|
||||||
|
|||||||
@@ -89,9 +89,7 @@ export default defineComponent({
|
|||||||
setup() {
|
setup() {
|
||||||
const { username } = useGitHubLogin()
|
const { username } = useGitHubLogin()
|
||||||
const { isReady } = useRepos()
|
const { isReady } = useRepos()
|
||||||
// eslint-disable-next-line prettier-vue/prettier
|
|
||||||
const { favoriteRepos, otherRepos, favoriteCheckboxes, toggleCheckbox } =
|
const { favoriteRepos, otherRepos, favoriteCheckboxes, toggleCheckbox } =
|
||||||
// eslint-disable-next-line prettier-vue/prettier
|
|
||||||
useRepoList()
|
useRepoList()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,3 +1,21 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { useFile } from '@/hooks/useFile.hook'
|
||||||
|
import { useQueryStackedNotes } from '@/hooks/useQueryStackedNotes.hook'
|
||||||
|
import { computed, defineAsyncComponent, onMounted } from 'vue'
|
||||||
|
|
||||||
|
const FluxNote = defineAsyncComponent(() => import('@/components/FluxNote.vue'))
|
||||||
|
|
||||||
|
const props = defineProps<{ user: string; repo: string; note: string }>()
|
||||||
|
|
||||||
|
const { resetStackedNotes } = useQueryStackedNotes()
|
||||||
|
const note = computed(() => props.note)
|
||||||
|
const { content } = useFile(note)
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
resetStackedNotes()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="share-notes">
|
<div class="share-notes">
|
||||||
<article class="message is-primary">
|
<article class="message is-primary">
|
||||||
@@ -17,38 +35,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { useFile } from '@/hooks/useFile.hook'
|
|
||||||
import { useQueryStackedNotes } from '@/hooks/useQueryStackedNotes.hook'
|
|
||||||
import { defineAsyncComponent, defineComponent, onMounted } from 'vue'
|
|
||||||
|
|
||||||
const FluxNote = defineAsyncComponent(() => import('@/components/FluxNote.vue'))
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: 'ShareNotes',
|
|
||||||
components: {
|
|
||||||
FluxNote
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
user: { type: String, required: true },
|
|
||||||
repo: { type: String, required: true },
|
|
||||||
note: { type: String, required: true }
|
|
||||||
},
|
|
||||||
setup(props) {
|
|
||||||
const { resetStackedNotes } = useQueryStackedNotes()
|
|
||||||
const { content } = useFile(props.note)
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
resetStackedNotes()
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
content
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.share-notes {
|
.share-notes {
|
||||||
background-color: var(--background-color);
|
background-color: var(--background-color);
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite'
|
|
||||||
import vue from '@vitejs/plugin-vue'
|
|
||||||
import path from 'path'
|
|
||||||
import { defineConfig } from 'vite'
|
|
||||||
import { VitePWA } from 'vite-plugin-pwa'
|
|
||||||
import { UserConfigExport } from 'vitest/dist/config'
|
import { UserConfigExport } from 'vitest/dist/config'
|
||||||
|
import { VitePWA } from 'vite-plugin-pwa'
|
||||||
|
import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite'
|
||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import path from 'path'
|
||||||
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
|
||||||
const mainColor = '#ffffff'
|
const mainColor = '#ffffff'
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user