feat: add download remotes as file
This commit is contained in:
parent
e09d42ecf6
commit
8f3832657b
@ -8,7 +8,17 @@ import {
|
|||||||
} from "solid-js";
|
} from "solid-js";
|
||||||
|
|
||||||
function List(props) {
|
function List(props) {
|
||||||
props = mergeProps({ items: [], showHeader: true, selectable: true }, props);
|
props = mergeProps(
|
||||||
|
{
|
||||||
|
items: [],
|
||||||
|
showHeader: true,
|
||||||
|
selectable: true,
|
||||||
|
onListItemsSelect: () => {},
|
||||||
|
onLazyLoad: () => {},
|
||||||
|
onListItemClick: () => {},
|
||||||
|
},
|
||||||
|
props
|
||||||
|
);
|
||||||
const [listItems, setListItems] = createSignal([]);
|
const [listItems, setListItems] = createSignal([]);
|
||||||
const selectedItems = createMemo(() =>
|
const selectedItems = createMemo(() =>
|
||||||
listItems()
|
listItems()
|
||||||
@ -31,16 +41,13 @@ function List(props) {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
if (!props.onListItemsSelect) return;
|
|
||||||
props.onListItemsSelect(selectedItems());
|
props.onListItemsSelect(selectedItems());
|
||||||
});
|
});
|
||||||
|
|
||||||
const observer = new IntersectionObserver((entries) => {
|
const observer = new IntersectionObserver((entries) => {
|
||||||
entries.forEach((entry) => {
|
entries.forEach((entry) => {
|
||||||
if (entry.isIntersecting) {
|
if (entry.isIntersecting) {
|
||||||
if (props.onLazyLoad) {
|
props.onLazyLoad();
|
||||||
props.onLazyLoad();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -61,7 +68,6 @@ function List(props) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function handleListItemClick(item) {
|
function handleListItemClick(item) {
|
||||||
if (!props.onListItemClick) return;
|
|
||||||
props.onListItemClick(item);
|
props.onListItemClick(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -61,9 +61,7 @@ const Serializer = (function () {
|
|||||||
return {
|
return {
|
||||||
id: remote.getId(),
|
id: remote.getId(),
|
||||||
title: remote.getTitle(),
|
title: remote.getTitle(),
|
||||||
commands: remote.getCommands().map((command) => ({
|
commands: serializeCommands(remote.getCommands()),
|
||||||
id: command.getId(),
|
|
||||||
})),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
30
www/src/tools/file-utils.js
Normal file
30
www/src/tools/file-utils.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
function FileUtils() {
|
||||||
|
function createJsonFile(jsonData, fileName) {
|
||||||
|
const json = JSON.stringify(jsonData, null, 2);
|
||||||
|
const file = new File([json], fileName, {
|
||||||
|
type: "text/json;charset=utf-8",
|
||||||
|
});
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
function downloadFile(file) {
|
||||||
|
console.log(file)
|
||||||
|
const url = URL.createObjectURL(file);
|
||||||
|
const link = document.createElement("a");
|
||||||
|
link.setAttribute("href", url);
|
||||||
|
link.setAttribute("download", file.name);
|
||||||
|
link.style.visibility = "hidden";
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
document.body.removeChild(link);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
createJsonFile,
|
||||||
|
downloadFile,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
FileUtils = new FileUtils();
|
||||||
|
|
||||||
|
export default FileUtils;
|
||||||
@ -1,13 +1,18 @@
|
|||||||
import { createResource, onMount } from "solid-js";
|
import { createMemo, createResource, createSignal, onMount } from "solid-js";
|
||||||
import List from "../../components/list";
|
import List from "../../components/list";
|
||||||
import RemotesService from "../../services/remotes-service";
|
import RemotesService from "../../services/remotes-service";
|
||||||
import CreateRemoteModal from "../../modals/create-remote-modal";
|
import CreateRemoteModal from "../../modals/create-remote-modal";
|
||||||
import DeleteRemoteModal from "../../modals/delete-remote-modal";
|
import DeleteRemoteModal from "../../modals/delete-remote-modal";
|
||||||
|
import FileUtils from "../../tools/file-utils";
|
||||||
|
import Serializer from "../../data/serializer";
|
||||||
|
import RemoteService from "../../services/remotes-service";
|
||||||
|
|
||||||
function RemotesList(props) {
|
function RemotesList(props) {
|
||||||
const [remotes, { refetch: refetchRemotes }] = createResource(
|
const [remotes, { refetch: refetchRemotes }] = createResource(
|
||||||
RemotesService.getRemotes
|
RemotesService.getRemotes
|
||||||
);
|
);
|
||||||
|
const [selectedRemotes, setSelectedRemotes] = createSignal([]);
|
||||||
|
const canExport = createMemo(() => selectedRemotes().length > 0);
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
refetchRemotes();
|
refetchRemotes();
|
||||||
@ -30,6 +35,25 @@ function RemotesList(props) {
|
|||||||
DeleteRemoteModal.Handler.show();
|
DeleteRemoteModal.Handler.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleListItemsSelect(items) {
|
||||||
|
setSelectedRemotes(items.map((item) => item.remote));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleExport() {
|
||||||
|
let remotes = await Promise.all(
|
||||||
|
selectedRemotes().map((remote) => RemoteService.getRemote(remote.getId()))
|
||||||
|
);
|
||||||
|
let files = remotes.map((remote) =>
|
||||||
|
FileUtils.createJsonFile(
|
||||||
|
Serializer.serializeRemote(remote),
|
||||||
|
`${remote.getTitle()}.remote.json`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
if (files.length >= 1) {
|
||||||
|
FileUtils.downloadFile(files[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div class="d-flex flex-row">
|
<div class="d-flex flex-row">
|
||||||
@ -37,9 +61,17 @@ function RemotesList(props) {
|
|||||||
{props.navigation ? props.navigation : null}
|
{props.navigation ? props.navigation : null}
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex flex-row justify-content-end flex-fill">
|
<div class="d-flex flex-row justify-content-end flex-fill">
|
||||||
|
<button
|
||||||
|
class="btn btn-dark me-2 mb-3"
|
||||||
|
disabled={!canExport()}
|
||||||
|
onClick={handleExport}
|
||||||
|
>
|
||||||
|
<i class="bi bi-box-arrow-up me-2"></i>
|
||||||
|
Export
|
||||||
|
</button>
|
||||||
<button class="btn btn-dark me-2 mb-3" onClick={handleNewRemote}>
|
<button class="btn btn-dark me-2 mb-3" onClick={handleNewRemote}>
|
||||||
<i class="bi bi-plus-square me-2"></i>
|
<i class="bi bi-plus-square me-2"></i>
|
||||||
New Remote
|
New
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -62,6 +94,7 @@ function RemotesList(props) {
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
onListItemClick={() => {}}
|
onListItemClick={() => {}}
|
||||||
|
onListItemsSelect={handleListItemsSelect}
|
||||||
items={(remotes() || []).map((remote) => ({
|
items={(remotes() || []).map((remote) => ({
|
||||||
id: {
|
id: {
|
||||||
html: <span class="font-monospace">{remote.getId()}</span>,
|
html: <span class="font-monospace">{remote.getId()}</span>,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user