Skip to content

Commit

Permalink
(feat) chapters... again
Browse files Browse the repository at this point in the history
  • Loading branch information
Phoeenix05 committed Aug 27, 2023
1 parent 94a2c3d commit 786e2b8
Show file tree
Hide file tree
Showing 10 changed files with 181 additions and 149 deletions.
24 changes: 19 additions & 5 deletions src/components/card/Manga.vue
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<script setup lang="ts">
import useFollowStore from '@/stores/following'
import { Output } from 'valibot'
const props = defineProps({
Expand All @@ -24,26 +25,38 @@ const image_src = ((): string => {
const cover_file = data.relationships.find((e: any) => e.type == 'cover_art').attributes.fileName
return `https://mangadex.org/covers/${id}/${cover_file}`
})()
const store = useFollowStore()
</script>

<template>
<template v-if="$props.variant == 'full'">
<div class="flex m-2 space-x-4 cursor-pointer">
<img
@click="navigateTo(`/manga/${id}`)"
:src="image_src"
class="w-32 rounded-sm"
/>
<div class="space-y-2">
<p class="text-xl font-bold w-[512px] truncate">{{ title }}</p>
<p class="w-[482px] h-24 overflow-hidden">{{ description }}</p>
<p
@click="navigateTo(`/manga/${id}`)"
class="text-xl font-bold w-[512px] truncate"
>
{{ title }}
</p>
<p
@click="navigateTo(`/manga/${id}`)"
class="w-[482px] h-24 overflow-hidden"
>
{{ description }}
</p>
<div class="space-x-2">
<UButton
@click="console.log('add')"
@click="store.add(id)"
label="Add"
size="xs"
/>
<UButton
@click="console.log('remove')"
@click="store.remove(id)"
label="Remove"
color="red"
size="xs"
Expand All @@ -56,8 +69,9 @@ const image_src = ((): string => {
<template v-if="$props.variant == 'compact'">
<div class="flex m-2 space-x-4 cursor-pointer">
<img
@click="navigateTo(`/manga/${id}`)"
:src="image_src"
class="w-48 rounded-sm"
class="w-32 rounded-sm"
/>
</div>
</template>
Expand Down
1 change: 1 addition & 0 deletions src/components/searchbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const search_query = ref('')
<input
type="text"
v-model="search_query"
class="mx-2 border-2 rounded-md border-neutral-700"
/>
<button @click="search_query ? navigateTo(`/search/${search_query}`) : null">Search</button>
</template>
1 change: 1 addition & 0 deletions src/layouts/default.vue
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<template>
<NuxtLink to="/">Home</NuxtLink>
<Searchbar />
<slot></slot>
</template>
Expand Down
23 changes: 23 additions & 0 deletions src/pages/chapter/[id].vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<script setup lang="ts">
import { fetch } from '@tauri-apps/api/http'
const { id } = useRoute().params
const { data, pending, error } = useAsyncData(async () => {
const response = await fetch<any>(`https://api.mangadex.org/at-home/server/${id}`, {
method: 'GET',
headers: {
'User-Agent': await userAgent()
}
})
return response.data
})
</script>

<template>
<img
v-if="!pending && !error"
v-for="img in data.chapter.data"
:src="`https://uploads.mangadex.org/data/${data.chapter.hash}/${img}`"
/>
</template>
54 changes: 52 additions & 2 deletions src/pages/index.vue
Original file line number Diff line number Diff line change
@@ -1,3 +1,53 @@
<script setup lang="ts"></script>
<script setup lang="ts">
import useFollowStore from '@/stores/following'
import { fetch } from '@tauri-apps/api/http'
import { Output } from 'valibot'
<template></template>
const { data, pending, error } = useAsyncData(async () => {
const followStore = useFollowStore()
const ids = followStore.idsQueryString
if (!ids.length) {
return
}
const url = construct_url('https://api.mangadex.org/manga', [
['includes[]', 'manga'],
['includes[]', 'author'],
['includes[]', 'artist'],
['includes[]', 'cover_art'],
...ids
])
const response = await fetch<Output<typeof MangaListSchema>>(url.toString(), {
method: 'GET',
headers: {
'User-Agent': await userAgent()
}
})
return response.data
})
</script>

<template>
<template v-if="!pending">
<template class="flex flex-wrap justify-center">
<CardManga
v-for="manga in data?.data"
:key="manga.id"
:storeId="manga.id"
:mangaData="manga"
variant="compact"
/>
</template>
</template>

<template v-else-if="pending">
<p>Loading...</p>
</template>

<template v-else-if="error">
<p>An error occurred</p>
<pre>{{ error }}</pre>
</template>
</template>
49 changes: 49 additions & 0 deletions src/pages/manga/[id].vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<script setup lang="ts">
import { fetch } from '@tauri-apps/api/http'
// Route params
const { id } = useRoute().params
const {
data: feed,
pending,
error
} = useAsyncData(async () => {
const url = construct_url(`https://api.mangadex.org/manga/${id}/feed`, [
['limit', '500'],
['translatedLanguage[]', 'en'],
['order[chapter]', 'desc']
])
const response = await fetch<any>(url, {
method: 'GET',
headers: {
'User-Agent': await userAgent()
}
})
return response.data
})
</script>

<template>
<template v-if="!pending">
<NuxtLink
class="mb-2 ml-2"
:to="`/chapter/${chapter.id}`"
v-for="chapter in feed.data"
>
{{ chapter.attributes.title || 'null' }}
<br />
</NuxtLink>
<pre>{{ JSON.stringify(feed, null, 2) }}</pre>
</template>

<template v-else-if="pending">
<p>Loading...</p>
</template>

<template v-else-if="error">
<p>An error occurred</p>
<pre>{{ error }}</pre>
</template>
</template>
4 changes: 3 additions & 1 deletion src/pages/search/[query].vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const { data, pending, error } = useAsyncData(async () => {
<template class="flex flex-wrap justify-center">
<CardManga
v-for="manga in data?.data"
:key="manga.id"
:storeId="manga.id"
:mangaData="manga"
variant="full"
Expand All @@ -47,6 +48,7 @@ const { data, pending, error } = useAsyncData(async () => {
</template>

<template v-else-if="error">
<p>An error occurred: {{ error }}</p>
<p>An error occurred</p>
<pre>{{ error }}</pre>
</template>
</template>
98 changes: 32 additions & 66 deletions src/stores/following.ts
Original file line number Diff line number Diff line change
@@ -1,66 +1,32 @@
// import SHA256 from 'crypto-js/sha256'

// /**
// * The way this is made is that `id` is present if the manga was found be searching it
// * in this app (so the manga has to be found on Mangadex for `id` to be present).
// *
// * `url` is present when you create a manga entry manually.
// *
// * `hash` field is used as the identifier for the DOM element. Mainly for easier deletion
// * from the `following` list.
// *
// * **Note**: If you use both `id` and `url` for creating a manga entry, well the deletion
// * should still work as expected. Though I haven't tested it yet.
// */
// type MangaSchema = {
// hash: string
// id: string
// url: string
// }

// export const useFollowingStore = defineStore('followed', {
// state: (): { data: MangaSchema[] } => {
// // TODO: Make this part prettier
// const data = localStorage.getItem('followed')
// const json = JSON.parse(data ? data : '[]')
// return { data: json }
// },
// getters: {
// all: (state) => state.data,
// range: (state) => (from: number, to: number) => state.data.slice(from, to)
// },
// actions: {
// /**
// * *This is a utility function*
// *
// * This function can be called anytime time to save the data to `localStorage`.
// * Though this function is called automatically by `addManga` and `removeManga` methods.
// */
// updateLocalStorage() {
// localStorage.setItem('followed', JSON.stringify(this.data))
// },
// /**
// * *This is a utility function*
// * @param hash
// */
// removeItem(hash: string) {
// const idx = this.data.findIndex((e) => e.hash === hash)
// this.data.splice(idx, 1)
// localStorage.setItem('followed', JSON.stringify(this.data))
// },
// add(id: string = '', url: string = '') {
// const hash = SHA256(id + url).toString()
// if (this.data.find((e) => e.hash === hash)) return

// this.data.unshift({ hash, id, url })
// this.updateLocalStorage()
// },
// remove(id: string = '', url: string = '') {
// const hash = SHA256(id + url).toString()
// this.removeItem(hash)
// },
// removeByHash(hash: string) {
// this.removeItem(hash)
// }
// }
// })
const useFollowStore = defineStore('followStore', {
state: () => {
const data: string[] = JSON.parse(localStorage.getItem('followed') || '[]')
return { data: data }
},
getters: {
ids: (state): string[] => state.data,
idsQueryString: (state): [string, string][] => {
const res: [string, string][] = []
state.data.forEach((id) => res.push(['ids[]', id]))
return res
}
},
actions: {
add(id: string) {
if (this.data.includes(id)) {
return
}
this.data.push(id)
localStorage.setItem('followed', JSON.stringify(this.data))
},
remove(id: string) {
if (!this.data.includes(id)) {
return
}
const idx = this.data.findIndex((v) => v == id)
this.data.splice(idx, 1)
localStorage.setItem('followed', JSON.stringify(this.data))
}
}
})
export default useFollowStore
74 changes: 0 additions & 74 deletions src/stores/history.ts
Original file line number Diff line number Diff line change
@@ -1,74 +0,0 @@
// import { SHA256 } from 'crypto-js'
// /**
// * History items do not need the 'url' field like Manga items
// * as only chapters available on mangadex can be added to the history.
// */
// type ChapterSchema = {
// hash: string
// id: string
// }

// export const useReadingHistory = defineStore('readingHistory', {
// state: (): { data: ChapterSchema[] } => {
// // TODO: Make this part prettier
// const data = localStorage.getItem('readingHistory')
// const json = JSON.parse(data ? data : '[]')
// return { data: json }
// },
// getters: {
// all: (state) => state.data,
// range: (state) => (from: number, to: number) => state.data.slice(from, to)
// },
// actions: {
// updateLocalStorage() {
// localStorage.setItem('readingHistory', JSON.stringify(this.data))
// },
// addItem(id: string) {
// const hash = SHA256(id).toString()

// // If item was already in the user's reading history
// // then remove it from the history and push it to the top of the list
// if (this.data.find((e) => e.hash === hash)) {
// const idx = this.data.findIndex((e) => e.hash === hash)
// this.data.splice(idx, 1)
// }

// this.data.unshift({ hash, id })
// this.updateLocalStorage()
// },
// removeItem(hash: string) {
// const idx = this.data.findIndex((e) => e.hash === hash)
// this.data.splice(idx, 1)
// this.updateLocalStorage()
// }
// }
// })

// export const useSearchHistory = defineStore('searchHistory', {
// state: (): { data: string[]; maxLength: number } => {
// // TODO: Make this part prettier
// const data = localStorage.getItem('searchHistory')
// const json = JSON.parse(data ? data : '[]')
// return { data: json, maxLength: 10 }
// },
// getters: {
// all: (state) => state.data
// },
// actions: {
// updateLocalStorage() {
// localStorage.setItem('searchHistory', JSON.stringify(this.data))
// },
// addItem(query: string) {
// if (this.data.includes(query)) {
// const idx = this.data.indexOf(query)
// this.data.splice(idx, 1)
// }
// this.data.unshift(query)

// if (this.data.length >= this.maxLength) {
// this.data.pop()
// }
// this.updateLocalStorage()
// }
// }
// })
Loading

0 comments on commit 786e2b8

Please sign in to comment.