feat: add download remotes as file

This commit is contained in:
Fritz Heiden 2025-04-15 00:26:34 +02:00
parent e09d42ecf6
commit 8f3832657b
4 changed files with 79 additions and 12 deletions

View File

@ -8,7 +8,17 @@ import {
} from "solid-js";
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 selectedItems = createMemo(() =>
listItems()
@ -31,17 +41,14 @@ function List(props) {
);
});
createEffect(() => {
if (!props.onListItemsSelect) return;
props.onListItemsSelect(selectedItems());
});
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
if (props.onLazyLoad) {
props.onLazyLoad();
}
}
});
});
@ -61,7 +68,6 @@ function List(props) {
});
function handleListItemClick(item) {
if (!props.onListItemClick) return;
props.onListItemClick(item);
}

View File

@ -61,9 +61,7 @@ const Serializer = (function () {
return {
id: remote.getId(),
title: remote.getTitle(),
commands: remote.getCommands().map((command) => ({
id: command.getId(),
})),
commands: serializeCommands(remote.getCommands()),
};
}

View 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;

View File

@ -1,13 +1,18 @@
import { createResource, onMount } from "solid-js";
import { createMemo, createResource, createSignal, onMount } from "solid-js";
import List from "../../components/list";
import RemotesService from "../../services/remotes-service";
import CreateRemoteModal from "../../modals/create-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) {
const [remotes, { refetch: refetchRemotes }] = createResource(
RemotesService.getRemotes
);
const [selectedRemotes, setSelectedRemotes] = createSignal([]);
const canExport = createMemo(() => selectedRemotes().length > 0);
onMount(() => {
refetchRemotes();
@ -30,6 +35,25 @@ function RemotesList(props) {
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 (
<>
<div class="d-flex flex-row">
@ -37,9 +61,17 @@ function RemotesList(props) {
{props.navigation ? props.navigation : null}
</div>
<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}>
<i class="bi bi-plus-square me-2"></i>
New Remote
New
</button>
</div>
</div>
@ -62,6 +94,7 @@ function RemotesList(props) {
},
]}
onListItemClick={() => {}}
onListItemsSelect={handleListItemsSelect}
items={(remotes() || []).map((remote) => ({
id: {
html: <span class="font-monospace">{remote.getId()}</span>,