Debug and refactor
This commit is contained in:
parent
612fc1cc25
commit
dc2d5cc460
|
@ -69,6 +69,7 @@ const goToLibraryShow = (item) => {
|
||||||
<!-- src="/img/haditha/sample-bgi.svg" -->
|
<!-- src="/img/haditha/sample-bgi.svg" -->
|
||||||
<p class="title">{{ item?._source?.title }}</p>
|
<p class="title">{{ item?._source?.title }}</p>
|
||||||
<p class="version">
|
<p class="version">
|
||||||
|
جلد
|
||||||
{{ item?._source?.vol_title + item?._source?.vol_num }}
|
{{ item?._source?.vol_title + item?._source?.vol_num }}
|
||||||
</p>
|
</p>
|
||||||
</ULink>
|
</ULink>
|
||||||
|
|
|
@ -20,6 +20,7 @@ const props = defineProps({
|
||||||
default: "",
|
default: "",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const emit = defineEmits(["on-bookmard-removed"]);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
|
@ -76,6 +77,7 @@ const removeFromFavorites = async (item = {}, index = 0) => {
|
||||||
title: item?._source?.title,
|
title: item?._source?.title,
|
||||||
};
|
};
|
||||||
httpService.postRequest(url, formData).then((res) => {
|
httpService.postRequest(url, formData).then((res) => {
|
||||||
|
emit("on-bookmard-removed", index);
|
||||||
// this.updateListAnswer(index, "tbookmark", 0);
|
// this.updateListAnswer(index, "tbookmark", 0);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -104,7 +106,7 @@ const removeFromFavorites = async (item = {}, index = 0) => {
|
||||||
</a>
|
</a>
|
||||||
<UButton
|
<UButton
|
||||||
v-if="route.name == 'hadithaFavorites'"
|
v-if="route.name == 'hadithaFavorites'"
|
||||||
@click="removeFromFavorites(item)"
|
@click="removeFromFavorites(item, index)"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
color="error"
|
color="error"
|
||||||
class="copy-btn"
|
class="copy-btn"
|
||||||
|
@ -133,6 +135,9 @@ const removeFromFavorites = async (item = {}, index = 0) => {
|
||||||
id: item?._source?.address.vol_id,
|
id: item?._source?.address.vol_id,
|
||||||
slug: hadithAddress(item),
|
slug: hadithAddress(item),
|
||||||
},
|
},
|
||||||
|
query: {
|
||||||
|
page_num: item?._source?.address?.page_num,
|
||||||
|
},
|
||||||
}"
|
}"
|
||||||
color="neutral"
|
color="neutral"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import hadithaApi from "@haditha/apis/hadithaApi";
|
import hadithaApi from "@haditha/apis/hadithaApi";
|
||||||
|
import headLinks from "@haditha/json/haditha/headLinks";
|
||||||
|
import headMetas from "@haditha/json/haditha/headMetas";
|
||||||
|
import { useInfiniteScroll } from "@vueuse/core";
|
||||||
|
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
layout: false,
|
layout: false,
|
||||||
|
@ -10,171 +13,98 @@ useHead({
|
||||||
title: `${import.meta.env.VITE_HADITH_PAGE_TITLE} | ذخیره ها`,
|
title: `${import.meta.env.VITE_HADITH_PAGE_TITLE} | ذخیره ها`,
|
||||||
meta: [
|
meta: [
|
||||||
{ name: "description", content: "کاوش با هوش مصنوعی در احادیث اسلامی" },
|
{ name: "description", content: "کاوش با هوش مصنوعی در احادیث اسلامی" },
|
||||||
{
|
...headMetas,
|
||||||
name: "msapplication-TileImage",
|
|
||||||
content: "/img/haditha/fav-icons/ms-icon-144x144.png",
|
|
||||||
},
|
|
||||||
{ name: "theme-color", content: "#ffffff" },
|
|
||||||
],
|
],
|
||||||
bodyAttrs: {
|
bodyAttrs: {
|
||||||
class: import.meta.env.VITE_HADITH_SYSTEM,
|
class: import.meta.env.VITE_HADITH_SYSTEM,
|
||||||
},
|
},
|
||||||
link: [
|
link: headLinks,
|
||||||
{
|
|
||||||
rel: "icon",
|
|
||||||
type: "image/x-icon",
|
|
||||||
href: "/img/haditha/fav-icons/favicon.ico",
|
|
||||||
},
|
|
||||||
{ rel: "manifest", href: "/img/haditha/fav-icons/manifest.json" },
|
|
||||||
// rel: icon
|
|
||||||
{
|
|
||||||
rel: "icon",
|
|
||||||
type: "image/png",
|
|
||||||
sizes: "16x16",
|
|
||||||
href: "/img/haditha/fav-icons/favicon-16x16.png",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
rel: "icon",
|
|
||||||
type: "image/png",
|
|
||||||
sizes: "32x32",
|
|
||||||
href: "/img/haditha/fav-icons/favicon-32x32.png",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
rel: "icon",
|
|
||||||
type: "image/png",
|
|
||||||
sizes: "96x96",
|
|
||||||
href: "/img/haditha/fav-icons/favicon-96x96.png",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
rel: "icon",
|
|
||||||
sizes: "192x192",
|
|
||||||
type: "image/png",
|
|
||||||
href: "/img/haditha/fav-icons/android-icon-192x192.png",
|
|
||||||
},
|
|
||||||
// rel: apple
|
|
||||||
{
|
|
||||||
rel: "apple-touch-icon",
|
|
||||||
sizes: "57x57",
|
|
||||||
href: "/img/haditha/fav-icons/apple-icon-57x57.png",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
rel: "apple-touch-icon",
|
|
||||||
sizes: "60x60",
|
|
||||||
href: "/img/haditha/fav-icons/android-icon-60x60.png",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
rel: "apple-touch-icon",
|
|
||||||
sizes: "72x72",
|
|
||||||
href: "/img/haditha/fav-icons/android-icon-72x72.png",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
rel: "apple-touch-icon",
|
|
||||||
sizes: "76x76",
|
|
||||||
href: "/img/haditha/fav-icons/android-icon-76x76.png",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
rel: "apple-touch-icon",
|
|
||||||
sizes: "114x114",
|
|
||||||
href: "/img/haditha/fav-icons/android-icon-114x114.png",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
rel: "apple-touch-icon",
|
|
||||||
sizes: "120x120",
|
|
||||||
href: "/img/haditha/fav-icons/android-icon-120x120.png",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
rel: "apple-touch-icon",
|
|
||||||
sizes: "144x144",
|
|
||||||
href: "/img/haditha/fav-icons/android-icon-144x144.png",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
rel: "apple-touch-icon",
|
|
||||||
sizes: "152x152",
|
|
||||||
href: "/img/haditha/fav-icons/android-icon-152x152.png",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
rel: "apple-touch-icon",
|
|
||||||
sizes: "180x180",
|
|
||||||
href: "/img/haditha/fav-icons/android-icon-180x180.png",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// #region refs
|
// #region refs
|
||||||
const loading = ref(false);
|
const el = ref(null);
|
||||||
const httpService = useNuxtApp()["$http"];
|
const httpService = useNuxtApp()["$http"];
|
||||||
|
|
||||||
|
const offset = useState("offset", () => 0);
|
||||||
|
const total = useState("total", () => 0);
|
||||||
|
const loading = useState("loading", () => false);
|
||||||
|
const hasMore = useState("hasMore", () => true);
|
||||||
|
|
||||||
// #endregion refs
|
// #endregion refs
|
||||||
|
|
||||||
// #region reactive
|
// #region reactive
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
// list: new Array(5).fill(0),
|
// list: new Array(5).fill(0),
|
||||||
list: [],
|
|
||||||
counts: [],
|
|
||||||
totalCounts: [],
|
|
||||||
pagination: {
|
pagination: {
|
||||||
page: 1,
|
page: 1,
|
||||||
pages: 1,
|
pages: 1,
|
||||||
offset: 0,
|
// offset: 0,
|
||||||
limit: 10,
|
limit: 500,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
// #endregion reactive
|
// #endregion reactive
|
||||||
|
|
||||||
// #region methods
|
// #region methods
|
||||||
|
|
||||||
const getCategories = async (dataType = "bookmark") => {
|
const getFavorites = async (dataType = "bookmark") => {
|
||||||
if (loading.value) return;
|
|
||||||
|
|
||||||
loading.value = true;
|
|
||||||
|
|
||||||
let url = repoUrl() + hadithaApi.favorite.getList;
|
let url = repoUrl() + hadithaApi.favorite.getList;
|
||||||
url = url.replace("@data_type", dataType);
|
url = url.replace("@data_type", dataType);
|
||||||
url = url.replace("@time_key", "all");
|
url = url.replace("@time_key", "all");
|
||||||
url = url.replace("@source", "main");
|
url = url.replace("@source", "main");
|
||||||
url = url.replace("@offset", state.pagination.offset);
|
url = url.replace("@offset", offset.value);
|
||||||
url = url.replace("@limit", state.pagination.limit);
|
url = url.replace("@limit", state.pagination.limit);
|
||||||
url = url.replace("@q", "none");
|
url = url.replace("@q", "none");
|
||||||
|
|
||||||
return await httpService
|
return await httpService.getRequest(url).then((res) => {
|
||||||
.getRequest(url)
|
console.info(res);
|
||||||
.then((res) => {
|
total.value = res.hits?.total?.value ?? 0;
|
||||||
state.list = res.hits.hits;
|
offset.value += state.pagination.limit;
|
||||||
state.totalCounts = res.hits.total.value;
|
return res;
|
||||||
loading.value = false;
|
|
||||||
// getCounts();
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.info(err);
|
|
||||||
loading.value = false;
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// const getCounts = async () => {
|
const { data: favoriteList } = await useAsyncData(
|
||||||
// let url = repoUrl() + hadithaApi.favorite.getCounts;
|
"favorites",
|
||||||
// url = url.replace("@data_type", "bookmark");
|
() => getFavorites(),
|
||||||
|
{
|
||||||
|
transform: (data) => data.hits.hits,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// await httpService
|
// Client-side infinite scroll
|
||||||
// .getRequest(url)
|
useInfiniteScroll(
|
||||||
// .then((res) => {
|
el,
|
||||||
// state.totalCounts = res.hits.total.value;
|
async () => {
|
||||||
// state.counts = res.aggregations.result.buckets;
|
if (!hasMore.value || loading.value) return;
|
||||||
// loading.value = false;
|
|
||||||
// })
|
|
||||||
// .catch((err) => {
|
|
||||||
// console.info(err);
|
|
||||||
// })
|
|
||||||
// .finally(() => {
|
|
||||||
// loading.value = false;
|
|
||||||
// });
|
|
||||||
// };
|
|
||||||
// #endregion methods
|
|
||||||
|
|
||||||
// #region hooks
|
loading.value = true;
|
||||||
onMounted(() => {
|
try {
|
||||||
getCategories();
|
await getFavorites().then((res) => {
|
||||||
});
|
const hits = res?.hits?.hits ?? [];
|
||||||
// #endregion methods
|
|
||||||
|
if (hits.length) {
|
||||||
|
// Use spread operator to create new array reference
|
||||||
|
favoriteList.value = [...favoriteList.value, ...hits];
|
||||||
|
} else {
|
||||||
|
hasMore.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
hasMore.value = false;
|
||||||
|
|
||||||
|
// console.error("Error loading more items:", error);
|
||||||
|
// Consider setting hasMore.value = false if you want to stop on error
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
distance: 100,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const updateList = (index) => {
|
||||||
|
favoriteList.value.splice(index, 1);
|
||||||
|
};
|
||||||
|
|
||||||
const HadithaLayout = defineAsyncComponent(() =>
|
const HadithaLayout = defineAsyncComponent(() =>
|
||||||
import("@haditha/layouts/HadithaLayout.vue")
|
import("@haditha/layouts/HadithaLayout.vue")
|
||||||
|
@ -196,7 +126,7 @@ const SearchList = defineAsyncComponent(() =>
|
||||||
|
|
||||||
<div class="text-logo">
|
<div class="text-logo">
|
||||||
<div
|
<div
|
||||||
v-if="state.list?.length"
|
v-show="favoriteList?.length"
|
||||||
class="search-box-container pb-0 flex justify-center"
|
class="search-box-container pb-0 flex justify-center"
|
||||||
>
|
>
|
||||||
<div class="search-list-contianer">
|
<div class="search-list-contianer">
|
||||||
|
@ -205,18 +135,21 @@ const SearchList = defineAsyncComponent(() =>
|
||||||
نتیجه
|
نتیجه
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ref="el" class="search-list firefox-scrollbar hadithaFavorites">
|
<div
|
||||||
|
ref="el"
|
||||||
|
class="search-list firefox-scrollbar hadithaFavorites"
|
||||||
|
>
|
||||||
<search-list
|
<search-list
|
||||||
no-data-text="هنوز چیزی ذخیره نکردهاید!"
|
no-data-text="هنوز چیزی ذخیره نکردهاید!"
|
||||||
no-data-icon="/img/haditha/save.png"
|
no-data-icon="/img/haditha/save.png"
|
||||||
:list="state.list"
|
:list="favoriteList"
|
||||||
:total="state.totalCounts"
|
@on-bookmard-removed="updateList"
|
||||||
></search-list>
|
></search-list>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<no-data
|
<no-data
|
||||||
v-else
|
v-show="favoriteList?.length == 0"
|
||||||
class="h-full w-full flex flex-col justify-center items-center"
|
class="h-full w-full flex flex-col justify-center items-center"
|
||||||
>
|
>
|
||||||
<img fit="auto" quality="80" src="/img/haditha/save.png" />
|
<img fit="auto" quality="80" src="/img/haditha/save.png" />
|
||||||
|
@ -238,6 +171,7 @@ const SearchList = defineAsyncComponent(() =>
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-logo {
|
.text-logo {
|
||||||
|
height: 100%;
|
||||||
padding-top: 4.5em;
|
padding-top: 4.5em;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,25 +61,23 @@ useHead({
|
||||||
// const page_num = computed({
|
// const page_num = computed({
|
||||||
// // getter
|
// // getter
|
||||||
// get() {
|
// get() {
|
||||||
// return state.selectedItem?.[0]._source.address.page_num - 1 >= 1
|
// return selectedItem.value?.[0]._source.address.page_num - 1 >= 1
|
||||||
// ? state.selectedItem?.[0]._source.address.page_num - 1
|
// ? selectedItem.value?.[0]._source.address.page_num - 1
|
||||||
// : 1;
|
// : 1;
|
||||||
// },
|
// },
|
||||||
// // setter
|
// // setter
|
||||||
// set(newValue) {
|
// set(newValue) {
|
||||||
// console.info(newValue);
|
|
||||||
|
|
||||||
// // handlePagination(1, newValue);
|
// // handlePagination(1, newValue);
|
||||||
// },
|
// },
|
||||||
// });
|
// });
|
||||||
|
|
||||||
const isModalOpen = ref(false);
|
const isModalOpen = ref(false);
|
||||||
const loading = ref(false);
|
|
||||||
const httpService = useNuxtApp()["$http"];
|
const httpService = useNuxtApp()["$http"];
|
||||||
const page_num = ref(1);
|
const loading = useState("loading", () => false);
|
||||||
|
const page_num = useState("page_num", () => 1);
|
||||||
|
const volumeInfo = useState("volumeInfo", () => {});
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
selectedItem: [] as Hit[],
|
|
||||||
treeItems: [
|
treeItems: [
|
||||||
{
|
{
|
||||||
title: "فصل اول",
|
title: "فصل اول",
|
||||||
|
@ -132,72 +130,51 @@ const state = reactive({
|
||||||
{ title: "فصل چهارم", icon: "vscode-icons:file-type-vue" },
|
{ title: "فصل چهارم", icon: "vscode-icons:file-type-vue" },
|
||||||
{ title: "فصل پنجم", icon: "vscode-icons:file-type-nuxt" },
|
{ title: "فصل پنجم", icon: "vscode-icons:file-type-nuxt" },
|
||||||
],
|
],
|
||||||
volumeInfo: {},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const pageIsLessThanOne = computed(() => {
|
|
||||||
return page_num.value <= 1;
|
|
||||||
});
|
|
||||||
const pageIsBiggerThanTotal = computed(() => {
|
|
||||||
const page_count = state.volumeInfo._source?.page_count;
|
|
||||||
return page_num.value + 1 >= page_count;
|
|
||||||
});
|
|
||||||
// #endregion refs and reactives
|
// #endregion refs and reactives
|
||||||
|
|
||||||
// #region methods
|
// #region methods
|
||||||
const fetchData = async () => {
|
const fetchData = async (page_first = 0) => {
|
||||||
|
const pageNum = route.query.page_num;
|
||||||
|
const volId = route.params.id;
|
||||||
|
page_num.value = pageNum ?? page_first;
|
||||||
|
|
||||||
let url = repoUrl() + hadithaApi.library.show;
|
let url = repoUrl() + hadithaApi.library.show;
|
||||||
url = url.replace("@appname", "monir");
|
url = url.replace("@appname", "monir");
|
||||||
url = url.replace("@page_start", state.volumeInfo._source?.page_first);
|
|
||||||
url = url.replace("@page_len", 1);
|
url = url.replace("@page_len", 1);
|
||||||
url = url.replace("@vol_id", state.volumeInfo?._source.id);
|
|
||||||
|
|
||||||
// const { data, status, error, refresh, clear } =
|
|
||||||
// await useHadithaSearchComposable<HadithResponseModel>(url, {
|
|
||||||
// method: "get",
|
|
||||||
// });
|
|
||||||
|
|
||||||
// if (status.value == "success") {
|
|
||||||
// state.selectedItem = <Hit[]>data.value.hits.hits;
|
|
||||||
|
|
||||||
// loading.value = false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
httpService
|
|
||||||
.getRequest(url)
|
|
||||||
.then((res: HadithResponseModel) => {
|
|
||||||
state.selectedItem = <Hit[]>res.hits.hits;
|
|
||||||
})
|
|
||||||
.finally(() => (loading.value = false));
|
|
||||||
};
|
|
||||||
const fetchVolume = async () => {
|
|
||||||
if (loading.value) return;
|
|
||||||
loading.value = true;
|
|
||||||
|
|
||||||
const volId = route.params.id;
|
|
||||||
|
|
||||||
let url = repoUrl() + hadithaApi.library.get;
|
|
||||||
url = url.replace("@vol_id", volId);
|
url = url.replace("@vol_id", volId);
|
||||||
|
url = url.replace("@page_start", page_num.value);
|
||||||
|
|
||||||
// fetch search list from backend(ssr)
|
return await httpService.getRequest(url).then((res) => {
|
||||||
// const { data, status, error, refresh, clear } =
|
volumeInfo.value = res.meta;
|
||||||
// await useHadithaSearchComposable<HadithResponseModel>(url, {
|
|
||||||
// method: "get",
|
|
||||||
// });
|
|
||||||
|
|
||||||
// if (status.value == "success") {
|
// for first time and navigating from book list.
|
||||||
// state.volumeInfo = data.value;
|
if (page_num.value == 0) page_num.value = volumeInfo.value.page_first;
|
||||||
// page_num.value = state.volumeInfo._source.page_first;
|
|
||||||
// }
|
|
||||||
|
|
||||||
httpService.getRequest(url).then((res: HadithResponseModel) => {
|
return res;
|
||||||
state.volumeInfo = res;
|
|
||||||
page_num.value = state.volumeInfo._source?.page_first;
|
|
||||||
fetchData();
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
fetchVolume();
|
// Server-side initial load
|
||||||
|
const { data: selectedItem } = await useAsyncData(
|
||||||
|
"libraryItem",
|
||||||
|
() => fetchData(),
|
||||||
|
{
|
||||||
|
transform: (data) => data.hits.hits,
|
||||||
|
// getCachedData: (key) => {
|
||||||
|
// return useNuxtApp().payload.data[key] || useNuxtApp().static.data[key];
|
||||||
|
// },
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const pageIsLessThanOne = computed(() => {
|
||||||
|
return +page_num.value <= 1;
|
||||||
|
});
|
||||||
|
const pageIsBiggerThanTotal = computed(() => {
|
||||||
|
const page_count = volumeInfo.value?.page_count;
|
||||||
|
return +page_num.value + 1 >= page_count;
|
||||||
|
});
|
||||||
|
|
||||||
const goToTheLibrary = (type: string) => {
|
const goToTheLibrary = (type: string) => {
|
||||||
router.push({
|
router.push({
|
||||||
|
@ -226,7 +203,7 @@ const handlePagination = (
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
|
|
||||||
const volId = route.params.id;
|
const volId = route.params.id;
|
||||||
const page_count = state.volumeInfo._source?.page_count;
|
const page_count = volumeInfo.value?.page_count;
|
||||||
|
|
||||||
const isPageBiggerThanOne = +page_num.value + prevNextIndicator > 0;
|
const isPageBiggerThanOne = +page_num.value + prevNextIndicator > 0;
|
||||||
const isPageLessThanTotal = +page_num.value + prevNextIndicator < page_count;
|
const isPageLessThanTotal = +page_num.value + prevNextIndicator < page_count;
|
||||||
|
@ -248,9 +225,11 @@ const handlePagination = (
|
||||||
httpService
|
httpService
|
||||||
.getRequest(url)
|
.getRequest(url)
|
||||||
.then((res: HadithResponseModel) => {
|
.then((res: HadithResponseModel) => {
|
||||||
state.selectedItem = res.hits.hits;
|
selectedItem.value = res.hits.hits;
|
||||||
})
|
})
|
||||||
.finally(() => (loading.value = false));
|
.finally(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
const handlePageChange = () => {
|
const handlePageChange = () => {
|
||||||
handlePagination(1, +page_num.value);
|
handlePagination(1, +page_num.value);
|
||||||
|
@ -283,7 +262,7 @@ const prepareTreeData = (data) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
getDataTree();
|
// getDataTree();
|
||||||
|
|
||||||
// #endregion methods
|
// #endregion methods
|
||||||
|
|
||||||
|
@ -330,7 +309,7 @@ const NavigationMenu = defineAsyncComponent(
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<UButton
|
<UButton
|
||||||
@click="onSearch"
|
@click="onSearch"
|
||||||
class="my-trailing-button search p-0"
|
class="my-trailing-button search p-0 close-btn text-[var(--ui-color-two)] hover:bg-gray-300"
|
||||||
icon="i-lucide-search"
|
icon="i-lucide-search"
|
||||||
variant=""
|
variant=""
|
||||||
size="xl"
|
size="xl"
|
||||||
|
@ -339,7 +318,7 @@ const NavigationMenu = defineAsyncComponent(
|
||||||
|
|
||||||
<UButton
|
<UButton
|
||||||
@click="goToTheLibrary"
|
@click="goToTheLibrary"
|
||||||
class="my-trailing-button close p-0 ms-8"
|
class="my-trailing-button close p-0 ms-8 close-btn text-[var(--ui-color-two)] hover:bg-gray-300"
|
||||||
icon="i-lucide:x"
|
icon="i-lucide:x"
|
||||||
variant=""
|
variant=""
|
||||||
size="xl"
|
size="xl"
|
||||||
|
@ -350,14 +329,11 @@ const NavigationMenu = defineAsyncComponent(
|
||||||
<div class="separator"></div>
|
<div class="separator"></div>
|
||||||
|
|
||||||
<div class="page-content firefox-scrollbar py-14 p-2">
|
<div class="page-content firefox-scrollbar py-14 p-2">
|
||||||
<template v-if="state.selectedItem?.length">
|
|
||||||
<p
|
<p
|
||||||
v-for="(parag, index) in state.selectedItem"
|
v-for="(parag, index) in selectedItem"
|
||||||
:key="index"
|
:key="index"
|
||||||
v-html="parag?._source?.content"
|
v-html="parag?._source?.content"
|
||||||
></p>
|
></p>
|
||||||
</template>
|
|
||||||
<no-data v-else></no-data>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="body-footer">
|
<div class="body-footer">
|
||||||
|
@ -373,9 +349,7 @@ const NavigationMenu = defineAsyncComponent(
|
||||||
:disabled="pageIsLessThanOne"
|
:disabled="pageIsLessThanOne"
|
||||||
/>
|
/>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<span class="total-pages">{{
|
<span class="total-pages">{{ volumeInfo?.page_count }}</span>
|
||||||
state.volumeInfo._source?.page_count
|
|
||||||
}}</span>
|
|
||||||
<span class="mx-2">/</span>
|
<span class="mx-2">/</span>
|
||||||
<UInput
|
<UInput
|
||||||
:disabled="loading"
|
:disabled="loading"
|
||||||
|
@ -634,6 +608,10 @@ const NavigationMenu = defineAsyncComponent(
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background-color: #eee;
|
background-color: #eee;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,13 +22,13 @@ useHead({
|
||||||
});
|
});
|
||||||
|
|
||||||
// #region refs
|
// #region refs
|
||||||
const el = useTemplateRef<HTMLElement>("el");
|
|
||||||
const httpService = useNuxtApp()["$http"];
|
const httpService = useNuxtApp()["$http"];
|
||||||
const total = ref(0);
|
const offset = useState("offset", () => 0);
|
||||||
const currentPage = useState("currentPage", () => 0);
|
const total = useState("total", () => 0);
|
||||||
// Client-side state
|
const loading = useState("loading", () => false);
|
||||||
const loading = ref(false);
|
const hasMore = useState("hasMore", () => true);
|
||||||
const hasMore = ref(true);
|
|
||||||
|
const el = ref(null);
|
||||||
// #endregion refs
|
// #endregion refs
|
||||||
|
|
||||||
// #region reactive
|
// #region reactive
|
||||||
|
@ -42,16 +42,16 @@ const state = reactive({
|
||||||
|
|
||||||
// #region methods
|
// #region methods
|
||||||
|
|
||||||
const getLibraryList = async (dataType = "bookmark") => {
|
const getLibraryList = async () => {
|
||||||
let url = repoUrl() + hadithaApi.library.list;
|
let url = repoUrl() + hadithaApi.library.list;
|
||||||
url = url.replace("@field_collapsed", "normal");
|
url = url.replace("@field_collapsed", "normal");
|
||||||
url = url.replace("@offset", currentPage.value);
|
url = url.replace("@offset", offset.value);
|
||||||
url = url.replace("@limit", state.pagination.limit);
|
url = url.replace("@limit", state.pagination.limit);
|
||||||
url = url.replace("@q", "none");
|
url = url.replace("@q", "none");
|
||||||
|
|
||||||
return await httpService.postRequest(url).then((res) => {
|
return await httpService.postRequest(url).then((res) => {
|
||||||
total.value = res.hits.total.value ?? 0;
|
total.value = res.hits?.total?.value ?? 0;
|
||||||
currentPage.value += state.pagination.limit;
|
offset.value += state.pagination.limit;
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
});
|
});
|
||||||
|
@ -60,32 +60,9 @@ const getLibraryList = async (dataType = "bookmark") => {
|
||||||
// Server-side initial load
|
// Server-side initial load
|
||||||
const { data: loadedItems } = await useAsyncData(
|
const { data: loadedItems } = await useAsyncData(
|
||||||
"libraryList",
|
"libraryList",
|
||||||
async () => {
|
() => getLibraryList(),
|
||||||
if (loading.value) return;
|
|
||||||
loading.value = true;
|
|
||||||
|
|
||||||
let url = repoUrl() + hadithaApi.library.list;
|
|
||||||
url = url.replace("@field_collapsed", "normal");
|
|
||||||
url = url.replace("@offset", currentPage.value);
|
|
||||||
url = url.replace("@limit", state.pagination.limit);
|
|
||||||
url = url.replace("@q", "none");
|
|
||||||
|
|
||||||
return await httpService
|
|
||||||
.postRequest(url)
|
|
||||||
.then((res) => {
|
|
||||||
total.value = res.hits.total.value ?? 0;
|
|
||||||
currentPage.value += state.pagination.limit;
|
|
||||||
return res;
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
loading.value = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
transform: (data) => data.hits.hits,
|
transform: (data) => data.hits.hits,
|
||||||
getCachedData: (key) => {
|
|
||||||
return useNuxtApp().payload.data[key] || useNuxtApp().static.data[key];
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -97,16 +74,21 @@ useInfiniteScroll(
|
||||||
|
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
try {
|
try {
|
||||||
// const nextPage = page.value + 1;
|
|
||||||
await getLibraryList().then((res) => {
|
await getLibraryList().then((res) => {
|
||||||
const hits = res.hits.hits;
|
const hits = res?.hits?.hits ?? [];
|
||||||
|
|
||||||
if (hits.length) {
|
if (hits.length > 0) {
|
||||||
loadedItems.value.push(...hits);
|
// Use spread operator to create new array reference
|
||||||
|
loadedItems.value = [...loadedItems.value, ...hits];
|
||||||
} else {
|
} else {
|
||||||
hasMore.value = false;
|
hasMore.value = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} catch (error) {
|
||||||
|
hasMore.value = false;
|
||||||
|
|
||||||
|
// console.error("Error loading more items:", error);
|
||||||
|
// Consider setting hasMore.value = false if you want to stop on error
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
|
@ -144,7 +126,6 @@ const CardList = defineAsyncComponent(
|
||||||
>
|
>
|
||||||
<!-- Client-side loaded content -->
|
<!-- Client-side loaded content -->
|
||||||
<card-list
|
<card-list
|
||||||
v-if="loadedItems?.length"
|
|
||||||
no-data-text="هنوز چیزی ذخیره نکردهاید!"
|
no-data-text="هنوز چیزی ذخیره نکردهاید!"
|
||||||
no-data-icon="/img/haditha/no-data.png"
|
no-data-icon="/img/haditha/no-data.png"
|
||||||
:list="loadedItems"
|
:list="loadedItems"
|
||||||
|
|
|
@ -269,6 +269,9 @@ const NavigationMenu = defineAsyncComponent(
|
||||||
id: selectedItem?._source?.address.vol_id,
|
id: selectedItem?._source?.address.vol_id,
|
||||||
slug: hadithAddress,
|
slug: hadithAddress,
|
||||||
},
|
},
|
||||||
|
query: {
|
||||||
|
page_num: selectedItem?._source?.address?.page_num,
|
||||||
|
},
|
||||||
}"
|
}"
|
||||||
color="neutral"
|
color="neutral"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
|
|
|
@ -167,7 +167,7 @@ const backgroundImageStyle = computed(() => {
|
||||||
// });
|
// });
|
||||||
let optimizedImageUrl = "/img/haditha/background.webp";
|
let optimizedImageUrl = "/img/haditha/background.webp";
|
||||||
|
|
||||||
if (showNoData.value) {
|
if (!showNoData.value) {
|
||||||
// optimizedImageUrl = img("/img/haditha/sub-header-bgi.webp", {
|
// optimizedImageUrl = img("/img/haditha/sub-header-bgi.webp", {
|
||||||
// quality: 80,
|
// quality: 80,
|
||||||
// });
|
// });
|
||||||
|
@ -231,8 +231,6 @@ const sendQuery = async (payload = {}) => {
|
||||||
// if (route.query.f_aik?.length) url += `&f_aik=${route.query.f_aik}`;
|
// if (route.query.f_aik?.length) url += `&f_aik=${route.query.f_aik}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.info(url);
|
|
||||||
|
|
||||||
return await httpService.postRequest(url, payload).then((res) => {
|
return await httpService.postRequest(url, payload).then((res) => {
|
||||||
total.value = res.hits.total.value ?? 0;
|
total.value = res.hits.total.value ?? 0;
|
||||||
offset.value += mainState.pagination.limit;
|
offset.value += mainState.pagination.limit;
|
||||||
|
@ -249,11 +247,8 @@ const sendQuery = async (payload = {}) => {
|
||||||
// Server-side initial load
|
// Server-side initial load
|
||||||
const { data: loadedItems } = await useAsyncData("search", () => sendQuery(), {
|
const { data: loadedItems } = await useAsyncData("search", () => sendQuery(), {
|
||||||
transform: (data) => data.hits.hits,
|
transform: (data) => data.hits.hits,
|
||||||
getCachedData: (key) => {
|
|
||||||
return useNuxtApp().payload.data[key] || useNuxtApp().static.data[key];
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
showNoData.value = Boolean(loadedItems.value?.length);
|
showNoData.value = loadedItems.value?.length == 0;
|
||||||
|
|
||||||
const onBeforeSendQuery = (from) => {
|
const onBeforeSendQuery = (from) => {
|
||||||
if (loading.value) return;
|
if (loading.value) return;
|
||||||
|
@ -270,11 +265,12 @@ const onBeforeSendQuery = (from) => {
|
||||||
if (searchTerm.value?.length) {
|
if (searchTerm.value?.length) {
|
||||||
sendQuery().then((res) => {
|
sendQuery().then((res) => {
|
||||||
loadedItems.value = res.hits.hits;
|
loadedItems.value = res.hits.hits;
|
||||||
showNoData.value = Boolean(loadedItems.value?.length);
|
showNoData.value = loadedItems.value?.length == 0;
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
searchTerm.value = "";
|
searchTerm.value = "";
|
||||||
|
loading.value = false;
|
||||||
loadedItems.value = [];
|
loadedItems.value = [];
|
||||||
showNoData.value = false;
|
showNoData.value = false;
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
|
@ -309,19 +305,17 @@ const onSearchButtonClick = () => {
|
||||||
if (loading.value) return;
|
if (loading.value) return;
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
|
|
||||||
// showclearButton.value = true;
|
sendQuery().then((res) => {
|
||||||
if (searchTerm.value?.length) {
|
loadedItems.value = res.hits.hits;
|
||||||
|
showNoData.value = loadedItems.value?.length == 0;
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const resetForm = () => {
|
||||||
searchTerm.value = "";
|
searchTerm.value = "";
|
||||||
loadedItems.value = [];
|
loadedItems.value = [];
|
||||||
showNoData.value = false;
|
showNoData.value = false;
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
} else {
|
|
||||||
sendQuery().then((res) => {
|
|
||||||
loadedItems.value = res.hits.hits;
|
|
||||||
showNoData.value = Boolean(loadedItems.value?.length);
|
|
||||||
loading.value = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// وقتی کاربر کلیدی فشار میدهد
|
// وقتی کاربر کلیدی فشار میدهد
|
||||||
|
@ -343,7 +337,7 @@ const setType = (type: string) => {
|
||||||
offset.value = 0;
|
offset.value = 0;
|
||||||
sendQuery().then((res) => {
|
sendQuery().then((res) => {
|
||||||
loadedItems.value = res.hits.hits;
|
loadedItems.value = res.hits.hits;
|
||||||
showNoData.value = Boolean(loadedItems.value?.length);
|
showNoData.value = loadedItems.value?.length == 0;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
// const setKey = (type: string) => {
|
// const setKey = (type: string) => {
|
||||||
|
@ -384,7 +378,7 @@ const onTypeSelectChanged = (value: string) => {
|
||||||
|
|
||||||
sendQuery().then((res) => {
|
sendQuery().then((res) => {
|
||||||
loadedItems.value = res.hits.hits;
|
loadedItems.value = res.hits.hits;
|
||||||
showNoData.value = Boolean(loadedItems.value?.length);
|
showNoData.value = loadedItems.value?.length == 0;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -438,7 +432,7 @@ const prepareSynonym = () => {
|
||||||
const onUpdateSwitch = () => {
|
const onUpdateSwitch = () => {
|
||||||
sendQuery(prepareSynonym()).then((res) => {
|
sendQuery(prepareSynonym()).then((res) => {
|
||||||
loadedItems.value = res.hits.hits;
|
loadedItems.value = res.hits.hits;
|
||||||
showNoData.value = Boolean(loadedItems.value?.length);
|
showNoData.value = loadedItems.value?.length == 0;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const onUpdateSubTitle = (subTitle) => {
|
const onUpdateSubTitle = (subTitle) => {
|
||||||
|
@ -446,7 +440,7 @@ const onUpdateSubTitle = (subTitle) => {
|
||||||
|
|
||||||
sendQuery(prepareSynonym()).then((res) => {
|
sendQuery(prepareSynonym()).then((res) => {
|
||||||
loadedItems.value = res.hits.hits;
|
loadedItems.value = res.hits.hits;
|
||||||
showNoData.value = Boolean(loadedItems.value?.length);
|
showNoData.value = loadedItems.value?.length == 0;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const onAddNewTitle = (subTitles) => {
|
const onAddNewTitle = (subTitles) => {
|
||||||
|
@ -458,7 +452,7 @@ const onAddNewTitle = (subTitles) => {
|
||||||
|
|
||||||
sendQuery(prepareSynonym()).then((res) => {
|
sendQuery(prepareSynonym()).then((res) => {
|
||||||
loadedItems.value = res.hits.hits;
|
loadedItems.value = res.hits.hits;
|
||||||
showNoData.value = Boolean(loadedItems.value?.length);
|
showNoData.value = loadedItems.value?.length == 0;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
// #endregion methods
|
// #endregion methods
|
||||||
|
@ -541,20 +535,26 @@ const SearchList = defineAsyncComponent(
|
||||||
</div>
|
</div>
|
||||||
<!-- 'similar-mode': route.query.f_aik?.length, -->
|
<!-- 'similar-mode': route.query.f_aik?.length, -->
|
||||||
<UButton
|
<UButton
|
||||||
class="my-trailing-button"
|
v-if="searchTerm.length"
|
||||||
:class="{
|
class="my-trailing-button close-mode"
|
||||||
'close-mode': searchTerm.length,
|
@click.prevent="resetForm"
|
||||||
}"
|
icon="i-lucide-x"
|
||||||
@click.prevent="onSearchButtonClick"
|
|
||||||
:icon="searchButtonIcon"
|
|
||||||
>
|
>
|
||||||
<!-- <UIcon name="i-lucide-search" /> -->
|
<!-- <UIcon name="i-lucide-search" /> -->
|
||||||
</UButton>
|
</UButton>
|
||||||
|
<UButton
|
||||||
|
v-else
|
||||||
|
class="my-trailing-button"
|
||||||
|
icon="i-haditha-search"
|
||||||
|
>
|
||||||
|
<!-- @click.prevent="onSearchButtonClick" -->
|
||||||
|
<!-- <UIcon name="i-lucide-search" /> -->
|
||||||
|
</UButton>
|
||||||
<!-- </client-only> -->
|
<!-- </client-only> -->
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="search-filter flex items-center my-3 justify-between"
|
class="search-filter flex items-center my-3 justify-between"
|
||||||
v-if="showNoData"
|
v-if="!showNoData"
|
||||||
>
|
>
|
||||||
<div class="flex items-center space-x-2">
|
<div class="flex items-center space-x-2">
|
||||||
<!-- #region معنایی -->
|
<!-- #region معنایی -->
|
||||||
|
@ -782,7 +782,7 @@ const SearchList = defineAsyncComponent(
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="!showNoData"
|
v-if="showNoData"
|
||||||
class="flex justify-center flex-col items-center mt-10"
|
class="flex justify-center flex-col items-center mt-10"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
|
@ -799,7 +799,7 @@ const SearchList = defineAsyncComponent(
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-show="showNoData"
|
v-show="!showNoData"
|
||||||
class="search-box-container pb-0 bg-white flex justify-center"
|
class="search-box-container pb-0 bg-white flex justify-center"
|
||||||
>
|
>
|
||||||
<div class="search-list-contianer">
|
<div class="search-list-contianer">
|
||||||
|
@ -826,11 +826,6 @@ const SearchList = defineAsyncComponent(
|
||||||
<p class="no-data-text">"نتیجهای یافت نشد!</p>
|
<p class="no-data-text">"نتیجهای یافت نشد!</p>
|
||||||
</no-data> -->
|
</no-data> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- <the-content-loading
|
|
||||||
v-show="loading"
|
|
||||||
class="absolute-positioning"
|
|
||||||
></the-content-loading> -->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user