|
15 | 15 |
|
16 | 16 | <!-- Main Content (only shows when config is loaded) --> |
17 | 17 | <div v-else> |
| 18 | + |
| 19 | + <ListModal |
| 20 | + ref="popularModalRef" |
| 21 | + :modal-id="'popularModal'" |
| 22 | + :title="'Trakt Popular Lists'" |
| 23 | + :items="state.lists_popular" |
| 24 | + :loading="state.lists_loading.popular" |
| 25 | + :pagination="state.pagination_popular" |
| 26 | + :list-type="'popular'" |
| 27 | + @add-list="addList" |
| 28 | + @close="closeModal('popular')" |
| 29 | + @page-change="handlePageChange" |
| 30 | + @opened="onModalOpened('popular')" |
| 31 | + @closed="onModalClosed('popular')" |
| 32 | + /> |
| 33 | + |
18 | 34 | <!-- Search modal --> |
19 | 35 | <div id="searchModal" ref="searchModal" tabindex="-1" aria-hidden="true" |
20 | 36 | class="hidden overflow-hidden fixed top-0 right-0 left-0 z-50 w-full md:inset-0 h-modal md:h-full"> |
|
503 | 519 | <div class="column flex rounded-md shadow-sm mt-5 w-full" role="group"> |
504 | 520 | <div class="flex rounded-md shadow-sm mt-5 w-full" role="group"> |
505 | 521 |
|
506 | | - <button @click="state.popularModal.show()" type="button" |
| 522 | + <button @click="showModal('popular')" type="button" |
507 | 523 | class="grow py-2 px-4 text-sm font-medium text-gray-900 bg-white rounded-l-lg border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-2 focus:ring-blue-700 focus:text-blue-700 dark:bg-gray-700 dark:border-gray-600 dark:text-white dark:hover:text-white dark:hover:bg-gray-600 dark:focus:ring-blue-500 dark:focus:text-white"> |
508 | 524 | Browse popular lists |
509 | 525 | </button> |
@@ -753,6 +769,7 @@ import { Modal, Dropdown } from 'flowbite' |
753 | 769 | import { useHead } from "@vueuse/head"; |
754 | 770 | import dropdown from 'vue-dropdowns'; |
755 | 771 | import VueToggles from "vue-toggles"; |
| 772 | +import ListModal from './components/ListModal.vue' |
756 | 773 |
|
757 | 774 | // Load sort options from static JSON |
758 | 775 | import * as sortOpts from '../../sortOpts.json'; |
@@ -925,6 +942,7 @@ watch(() => clientConfig.value.oauthClientId, (newId) => { |
925 | 942 | const searchModal = ref(); |
926 | 943 | const installModal = ref(); |
927 | 944 | const popularModal = ref(); |
| 945 | +const popularModalRef = ref(); |
928 | 946 | const trendingModal = ref(); |
929 | 947 | const personalModal = ref(); |
930 | 948 |
|
@@ -967,6 +985,68 @@ onMounted(async () => { |
967 | 985 | setTimeout(updateOAuthUrl, 500); |
968 | 986 | }); |
969 | 987 |
|
| 988 | +// Function to show modal |
| 989 | +const showModal = async (modalType) => { |
| 990 | + // Get the modal ref |
| 991 | + const modalRef = getModalRef(modalType) |
| 992 | + |
| 993 | + if (modalRef?.value?.show) { |
| 994 | + // Show the modal |
| 995 | + modalRef.value.show() |
| 996 | + |
| 997 | + // Load data if needed |
| 998 | + if (shouldLoadData(modalType)) { |
| 999 | + await loadPage(modalType) |
| 1000 | + } |
| 1001 | + } |
| 1002 | +} |
| 1003 | +
|
| 1004 | +// Function to close modal |
| 1005 | +const closeModal = async (modalType) => { |
| 1006 | + // Get the modal ref |
| 1007 | + const modalRef = getModalRef(modalType) |
| 1008 | + |
| 1009 | + if (modalRef?.value?.show) { |
| 1010 | + // Show the modal |
| 1011 | + modalRef.value.hide() |
| 1012 | + } |
| 1013 | +} |
| 1014 | +
|
| 1015 | +// Helper function to get modal ref |
| 1016 | +const getModalRef = (modalType) => { |
| 1017 | + switch (modalType) { |
| 1018 | + case 'personal': return personalModalRef |
| 1019 | + case 'popular': return popularModalRef |
| 1020 | + case 'trending': return trendingModalRef |
| 1021 | + case 'search': return searchModalRef |
| 1022 | + default: return null |
| 1023 | + } |
| 1024 | +} |
| 1025 | +
|
| 1026 | +// Helper function to check if data should be loaded |
| 1027 | +const shouldLoadData = (modalType) => { |
| 1028 | + const lists = { |
| 1029 | + personal: state.lists_personal, |
| 1030 | + popular: state.lists_popular, |
| 1031 | + trending: state.lists_trending, |
| 1032 | + search: state.searchResults |
| 1033 | + } |
| 1034 | + |
| 1035 | + return !lists[modalType] || lists[modalType].length === 0 |
| 1036 | +} |
| 1037 | +
|
| 1038 | +// Modal event handlers |
| 1039 | +const onModalOpened = (modalType) => { |
| 1040 | + console.log(`${modalType} modal opened`) |
| 1041 | + // Any logic you need when modal opens |
| 1042 | +} |
| 1043 | +
|
| 1044 | +const onModalClosed = (modalType) => { |
| 1045 | + console.log(`${modalType} modal closed`) |
| 1046 | + // Any cleanup when modal closes |
| 1047 | +} |
| 1048 | +
|
| 1049 | +
|
970 | 1050 | // Add reactive state for OAuth button |
971 | 1051 | const authButtonState = reactive({ |
972 | 1052 | text: 'Login to Trakt.tv', |
@@ -1365,6 +1445,17 @@ function nextPage(listType) { |
1365 | 1445 | loadPage(listType); |
1366 | 1446 | } |
1367 | 1447 |
|
| 1448 | +const handlePageChange = async (payload) => { |
| 1449 | + const { listType, page } = payload |
| 1450 | + |
| 1451 | + // Update pagination state |
| 1452 | + state[`pagination_${listType}`].page = page |
| 1453 | + |
| 1454 | + // Load the page |
| 1455 | + await loadPage(listType) |
| 1456 | +} |
| 1457 | +
|
| 1458 | +
|
1368 | 1459 | async function loadPage(listType) { |
1369 | 1460 | // Don't start another load if already loading |
1370 | 1461 | if (state.lists_loading[listType]) return; |
|
0 commit comments