|
1 | 1 | <template> |
2 | 2 | <div class="bg-white dark:bg-gray-800 shadow-xl rounded-2xl overflow-hidden border border-gray-200 dark:border-gray-700"> |
3 | | - <div class="px-6 py-5 border-b border-gray-200 dark:border-gray-700 bg-gradient-to-r from-gray-50 to-white dark:from-gray-800 dark:to-gray-800/50"> |
| 3 | + <div class="px-6 py-5 border-b border-gray-200 dark:border-gray-700 bg-gradient-to-r from-gray-50 to-white dark:from-gray-800 dark:to-gray-800/50 flex items-center justify-between"> |
4 | 4 | <h1 class="text-2xl font-bold text-gray-900 dark:text-white capitalize">{{ folderName }}</h1> |
| 5 | + <button |
| 6 | + @click="handleRefresh" |
| 7 | + :disabled="isRefreshing" |
| 8 | + class="p-2 text-gray-600 dark:text-gray-400 hover:text-indigo-600 dark:hover:text-indigo-400 rounded-lg hover:bg-indigo-50 dark:hover:bg-gray-700/50 transition-all duration-200 disabled:opacity-70 disabled:cursor-not-allowed" |
| 9 | + :title="isRefreshing ? 'Refreshing...' : 'Refresh emails'" |
| 10 | + > |
| 11 | + <svg v-if="!isRefreshing" class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
| 12 | + <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" /> |
| 13 | + </svg> |
| 14 | + <svg v-else class="w-5 h-5 animate-spin" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
| 15 | + <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle> |
| 16 | + <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path> |
| 17 | + </svg> |
| 18 | + </button> |
5 | 19 | </div> |
6 | 20 | <ul v-if="emails.length > 0" class="divide-y divide-gray-100 dark:divide-gray-700/50"> |
7 | 21 | <li v-for="email in emails" :key="email.id" class="group relative transition-all duration-200" :class="{ 'bg-indigo-50/30 dark:bg-indigo-900/10': !email.read, 'hover:bg-gradient-to-r hover:from-indigo-50/50 hover:to-purple-50/30 dark:hover:from-indigo-900/10 dark:hover:to-purple-900/10': true }"> |
|
59 | 73 |
|
60 | 74 | <script setup lang="ts"> |
61 | 75 | import { storeToRefs } from "pinia"; |
62 | | -import { computed, onMounted, watch } from "vue"; |
| 76 | +import { computed, onMounted, onUnmounted, watch, ref } from "vue"; |
63 | 77 | import { useRoute } from "vue-router"; |
64 | 78 | import { useEmailStore } from "@/stores/emails"; |
65 | 79 | import { useFolderStore } from "@/stores/folders"; |
66 | 80 | import type { Email } from "@/types"; |
67 | 81 |
|
68 | 82 | const emailStore = useEmailStore(); |
69 | | -const { emails } = storeToRefs(emailStore); |
| 83 | +const { emails, isRefreshing } = storeToRefs(emailStore); |
70 | 84 | const folderStore = useFolderStore(); |
71 | 85 | const { folders } = storeToRefs(folderStore); |
72 | 86 | const route = useRoute(); |
73 | 87 |
|
| 88 | +let refreshInterval: ReturnType<typeof setInterval> | null = null; |
| 89 | +
|
74 | 90 | const folderId = computed(() => route.params.folder as string); |
75 | 91 |
|
76 | 92 | const folderName = computed(() => { |
77 | 93 | const foundFolder = folders.value.find((f) => f.id === folderId.value); |
78 | 94 | return foundFolder ? foundFolder.name : folderId.value; |
79 | 95 | }); |
80 | 96 |
|
| 97 | +const startAutoRefresh = () => { |
| 98 | + if (refreshInterval) clearInterval(refreshInterval); |
| 99 | + refreshInterval = setInterval(() => { |
| 100 | + emailStore.fetchEmails(route.params.mailboxId as string, { |
| 101 | + folder: folderId.value, |
| 102 | + }); |
| 103 | + }, 30000); |
| 104 | +}; |
| 105 | +
|
| 106 | +const stopAutoRefresh = () => { |
| 107 | + if (refreshInterval) { |
| 108 | + clearInterval(refreshInterval); |
| 109 | + refreshInterval = null; |
| 110 | + } |
| 111 | +}; |
| 112 | +
|
| 113 | +const handleRefresh = () => { |
| 114 | + emailStore.fetchEmails(route.params.mailboxId as string, { |
| 115 | + folder: folderId.value, |
| 116 | + }); |
| 117 | +}; |
| 118 | +
|
81 | 119 | onMounted(() => { |
82 | 120 | emailStore.fetchEmails(route.params.mailboxId as string, { |
83 | 121 | folder: folderId.value, |
84 | 122 | }); |
| 123 | + startAutoRefresh(); |
| 124 | +}); |
| 125 | +
|
| 126 | +onUnmounted(() => { |
| 127 | + stopAutoRefresh(); |
85 | 128 | }); |
86 | 129 |
|
87 | 130 | watch(folderId, (newFolderId) => { |
|
0 commit comments