|
247 | 247 | </nut-button> |
248 | 248 | </div> |
249 | 249 | <div class="sub-item-swipe-btn-wrapper"> |
250 | | - <a |
251 | | - :href="`${host}/api/${props.type}/${encodeURIComponent(name)}?raw=1`" |
252 | | - target="_blank" |
| 250 | + <nut-button |
| 251 | + shape="square" |
| 252 | + type="success" |
| 253 | + class="sub-item-swipe-btn" |
| 254 | + @click="onClickExport" |
253 | 255 | > |
254 | | - <nut-button shape="square" type="success" class="sub-item-swipe-btn"> |
255 | | - <font-awesome-icon icon="fa-solid fa-file-export" /> |
256 | | - </nut-button> |
257 | | - </a> |
| 256 | + <font-awesome-icon icon="fa-solid fa-file-export" /> |
| 257 | + </nut-button> |
258 | 258 | </div> |
259 | 259 | <!-- preview --> |
260 | 260 | <!-- <div class="sub-item-swipe-btn-wrapper"> |
|
287 | 287 | </nut-button> |
288 | 288 | </div> |
289 | 289 | <div class="sub-item-swipe-btn-wrapper"> |
290 | | - <a |
291 | | - :href="`${host}/api/${props.type}/${encodeURIComponent(name)}?raw=1`" |
292 | | - target="_blank" |
| 290 | + <nut-button |
| 291 | + shape="square" |
| 292 | + type="success" |
| 293 | + class="sub-item-swipe-btn" |
| 294 | + @click="onClickExport" |
293 | 295 | > |
294 | | - <nut-button shape="square" type="success" class="sub-item-swipe-btn"> |
295 | | - <font-awesome-icon icon="fa-solid fa-file-export" /> |
296 | | - </nut-button> |
297 | | - </a> |
| 296 | + <font-awesome-icon icon="fa-solid fa-file-export" /> |
| 297 | + </nut-button> |
298 | 298 | </div> |
299 | 299 | <div class="sub-item-swipe-btn-wrapper"> |
300 | 300 | <nut-button |
@@ -345,6 +345,7 @@ import { createGithubProxyUrlRewriter } from "@/utils/githubProxy"; |
345 | 345 | import { resolveImageFit } from "@/utils/iconFit"; |
346 | 346 | import { isMobile } from "@/utils/isMobile"; |
347 | 347 | import { openManagedDeleteDialog } from "@/utils/archive"; |
| 348 | +import { downloadBlobResponse } from "@/utils/download"; |
348 | 349 | import CompareTable from "@/views/CompareTable.vue"; |
349 | 350 |
|
350 | 351 | const props = defineProps<{ |
@@ -924,26 +925,27 @@ const onClickCopyConfig = async () => { |
924 | 925 | showNotify({ title: t("subPage.copyConfigNotify.succeed") }); |
925 | 926 | closeExpandedMenu(); |
926 | 927 | }; |
927 | | -// const onClickExport = async () => { |
928 | | -// swipeController() |
929 | | -// let data: Sub | Collection; |
930 | | -// switch (props.type) { |
931 | | -// case "sub": |
932 | | -// data = JSON.parse(JSON.stringify(toRaw(props.sub))); |
933 | | -// break; |
934 | | -// case "collection": |
935 | | -// data = JSON.parse(JSON.stringify(toRaw(props.collection))); |
936 | | -// break; |
937 | | -// } |
938 | | -// data.name += `-exportedAt${new Date().toLocaleDateString()} ${new Date().toLocaleTimeString()}`; |
939 | | -
|
940 | | -// Toast.loading(t("subPage.copyConfigNotify.loading"), { id: "exportConfig" }); |
941 | | -// // await subsApi.createSub(props.type + "s", data); |
942 | | -// // await subsStore.fetchSubsData(); |
943 | | -// Toast.hide("exportConfig"); |
944 | | -// showNotify({ title: t("subPage.copyConfigNotify.succeed") }); |
945 | | -// swipe.value.close(); |
946 | | -// }; |
| 928 | +const onClickExport = async () => { |
| 929 | + Toast.loading(t("subPage.exportConfigNotify.loading"), { id: "exportConfig" }); |
| 930 | + try { |
| 931 | + downloadBlobResponse( |
| 932 | + await subsApi.exportOne(props.type, name), |
| 933 | + `sub-store_${props.type}_${name}.json`, |
| 934 | + ); |
| 935 | + showNotify({ title: t("subPage.exportConfigNotify.succeed") }); |
| 936 | + } catch (e) { |
| 937 | + console.error(e); |
| 938 | + showNotify({ |
| 939 | + type: "danger", |
| 940 | + title: t("subPage.exportConfigNotify.failed", { |
| 941 | + e: e instanceof Error ? e.message : e, |
| 942 | + }), |
| 943 | + }); |
| 944 | + } finally { |
| 945 | + Toast.hide("exportConfig"); |
| 946 | + closeExpandedMenu(); |
| 947 | + } |
| 948 | +}; |
947 | 949 |
|
948 | 950 | const onClickEdit = () => { |
949 | 951 | router.push(`/edit/${props.type}s/${encodeURIComponent(name)}`); |
|
0 commit comments