mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-12 07:04:52 +09:00
Refactor HostUpdatesEvent, InstanceDetailsUpdatesEvent, ModUpdatesEvent, ModPackUpdatesEvent and UserUpdatesEvent to have multiple updates of the entities they support in each event. This is intended to make the events capable of syncing the entire list that they represent.
92 lines
2.3 KiB
TypeScript
92 lines
2.3 KiB
TypeScript
import { useEffect, useContext, useState } from "react";
|
|
import ControlContext from "../components/ControlContext";
|
|
|
|
import * as lib from "@clusterio/lib";
|
|
|
|
const { logger } = lib;
|
|
|
|
export type InstanceState = Partial<lib.InstanceDetails> & {
|
|
loading?: boolean,
|
|
present?: boolean,
|
|
missing?: boolean,
|
|
}
|
|
|
|
export function useInstance(id: number): [InstanceState, ()=>void] {
|
|
let control = useContext(ControlContext);
|
|
let [instance, setInstance] = useState<InstanceState>({ loading: true });
|
|
|
|
function updateInstance() {
|
|
control.send(new lib.InstanceDetailsGetRequest(id)).then(updatedInstance => {
|
|
setInstance({ ...updatedInstance, present: true });
|
|
}).catch((err: any) => {
|
|
logger.error(`Failed to get instance: ${err}`);
|
|
setInstance({ missing: true });
|
|
});
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (!Number.isInteger(id)) {
|
|
setInstance({ missing: true });
|
|
return undefined;
|
|
}
|
|
updateInstance();
|
|
|
|
function updateHandler(newInstances: lib.InstanceDetails[]) {
|
|
const newInstance = newInstances.find(i => i.id === id);
|
|
if (newInstance) {
|
|
setInstance({ ...newInstance, present: true });
|
|
}
|
|
}
|
|
|
|
control.instanceUpdate.subscribe(updateHandler);
|
|
return () => {
|
|
control.instanceUpdate.unsubscribe(updateHandler);
|
|
};
|
|
}, [id]);
|
|
|
|
return [instance, updateInstance];
|
|
}
|
|
|
|
export function useInstanceList() {
|
|
let control = useContext(ControlContext);
|
|
let [instanceList, setInstanceList] = useState<lib.InstanceDetails[]>([]);
|
|
|
|
function updateInstanceList() {
|
|
control.send(new lib.InstanceDetailsListRequest()).then(instances => {
|
|
setInstanceList(instances);
|
|
}).catch(err => {
|
|
logger.error(`Failed to list instances:\n${err}`);
|
|
});
|
|
}
|
|
|
|
useEffect(() => {
|
|
updateInstanceList();
|
|
|
|
function updateHandler(newInstances: lib.InstanceDetails[]) {
|
|
setInstanceList(oldList => {
|
|
let newList = oldList.concat();
|
|
for (const newInstance of newInstances) {
|
|
let index = newList.findIndex(s => s.id === newInstance.id);
|
|
if (newInstance.status !== "deleted") {
|
|
if (index !== -1) {
|
|
newList[index] = newInstance;
|
|
} else {
|
|
newList.push(newInstance);
|
|
}
|
|
} else if (index !== -1) {
|
|
newList.splice(index, 1);
|
|
}
|
|
}
|
|
return newList;
|
|
});
|
|
}
|
|
|
|
control.instanceUpdate.subscribe(updateHandler);
|
|
return () => {
|
|
control.instanceUpdate.unsubscribe(updateHandler);
|
|
};
|
|
}, []);
|
|
|
|
return [instanceList];
|
|
}
|