Quest editor layout is now persisted.

This commit is contained in:
Daan Vanden Bosch 2019-07-24 16:44:17 +02:00
parent 25b7a4869b
commit 52376193ae
6 changed files with 155 additions and 66 deletions

View File

@ -1,6 +1,8 @@
import { Persister } from "./Persister";
import { Server, HuntMethod } from "../domain";
const METHOD_USER_TIMES_KEY = "HuntMethodStore.methodUserTimes";
class HuntMethodPersister extends Persister {
persist_method_user_times(hunt_methods: HuntMethod[], server: Server): void {
const user_times: PersistedUserTimes = {};
@ -11,7 +13,7 @@ class HuntMethodPersister extends Persister {
}
}
this.persist_for_server(server, "HuntMethodStore.methodUserTimes", user_times);
this.persist_for_server(server, METHOD_USER_TIMES_KEY, user_times);
}
async load_method_user_times(
@ -20,7 +22,7 @@ class HuntMethodPersister extends Persister {
): Promise<HuntMethod[]> {
const user_times = await this.load_for_server<PersistedUserTimes>(
server,
"HuntMethodStore.methodUserTimes"
METHOD_USER_TIMES_KEY
);
if (user_times) {

View File

@ -3,11 +3,13 @@ import { WantedItem } from "../stores/HuntOptimizerStore";
import { item_type_stores } from "../stores/ItemTypeStore";
import { Persister } from "./Persister";
const WANTED_ITEMS_KEY = "HuntOptimizerStore.wantedItems";
class HuntOptimizerPersister extends Persister {
persist_wanted_items(server: Server, wanted_items: WantedItem[]): void {
this.persist_for_server(
server,
"HuntOptimizerStore.wantedItems",
WANTED_ITEMS_KEY,
wanted_items.map(
({ item_type, amount }): PersistedWantedItem => ({
itemTypeId: item_type.id,
@ -22,7 +24,7 @@ class HuntOptimizerPersister extends Persister {
const persisted_wanted_items = await this.load_for_server<PersistedWantedItem[]>(
server,
"HuntOptimizerStore.wantedItems"
WANTED_ITEMS_KEY
);
const wanted_items: WantedItem[] = [];

View File

@ -0,0 +1,57 @@
import { Persister } from "./Persister";
import { throttle } from "lodash";
const LAYOUT_CONFIG_KEY = "QuestEditorUiPersister.layout_config";
class QuestEditorUiPersister extends Persister {
persist_layout_config = throttle(
(config: any) => {
this.persist(LAYOUT_CONFIG_KEY, config);
},
1000,
{ leading: false, trailing: true }
);
async load_layout_config(components: string[], default_config: any): Promise<any> {
const config = await this.load(LAYOUT_CONFIG_KEY);
let valid = this.verify_layout_config(config, new Set(components));
if (valid) {
return config;
} else {
return default_config;
}
}
private verify_layout_config(
config: any,
components: Set<string>,
found: Set<string> = new Set(),
first: boolean = true
): boolean {
if (!config) {
return false;
}
if (config.component) {
if (!components.has(config.component)) {
return false;
} else {
found.add(config.component);
}
}
if (config.content) {
for (const child of config.content) {
if (!this.verify_layout_config(child, components, found, false)) {
return false;
}
}
}
return first ? components.size === found.size : true;
}
}
export const quest_editor_ui_persister = new QuestEditorUiPersister();

View File

@ -38,7 +38,7 @@
}
body {
overflow: hidden;
overflow: hidden; // Necessary for golden layout.
}
// react-virtualized

View File

@ -9,6 +9,64 @@ import { QuestInfoComponent } from "./QuestInfoComponent";
import { QuestRendererComponent } from "./QuestRendererComponent";
import { ScriptEditorComponent } from "./ScriptEditorComponent";
import { Toolbar } from "./Toolbar";
import { quest_editor_ui_persister } from "../../persistence/QuestEditorUiPersister";
import Logger from "js-logger";
const logger = Logger.get("ui/quest_editor/QuestEditorComponent");
const DEFAULT_LAYOUT_CONFIG = {
settings: {
showPopoutIcon: false,
},
dimensions: {
headerHeight: 28,
},
labels: {
close: "Close",
maximise: "Maximise",
minimise: "Minimise",
popout: "Open in new window",
},
content: [
{
type: "row",
content: [
{
title: "Info",
type: "react-component",
component: QuestInfoComponent.name,
isClosable: false,
width: 3,
},
{
type: "stack",
width: 9,
content: [
{
title: "3D View",
type: "react-component",
component: QuestRendererComponent.name,
isClosable: false,
},
{
title: "Script",
type: "react-component",
component: ScriptEditorComponent.name,
isClosable: false,
},
],
},
{
title: "Entity",
type: "react-component",
component: EntityInfoComponent.name,
isClosable: false,
width: 2,
},
],
},
],
};
@observer
export class QuestEditorComponent extends Component {
@ -20,68 +78,39 @@ export class QuestEditorComponent extends Component {
window.addEventListener("resize", this.resize);
setTimeout(() => {
setTimeout(async () => {
if (this.layout_element.current && !this.layout) {
this.layout = new GoldenLayout(
{
settings: {
showPopoutIcon: false,
},
dimensions: {
headerHeight: 28,
},
labels: {
close: "Close",
maximise: "Maximise",
minimise: "Minimise",
popout: "Open in new window",
},
content: [
{
type: "row",
content: [
{
title: "Info",
type: "react-component",
component: "QuestInfoComponent",
isClosable: false,
width: 3,
},
{
type: "stack",
width: 9,
content: [
{
title: "3D View",
type: "react-component",
component: "QuestRendererComponent",
isClosable: false,
},
{
title: "Script",
type: "react-component",
component: "ScriptEditorComponent",
isClosable: false,
},
],
},
{
title: "Entity",
type: "react-component",
component: "EntityInfoComponent",
isClosable: false,
width: 2,
},
],
},
],
},
this.layout_element.current
const config = await quest_editor_ui_persister.load_layout_config(
[
QuestInfoComponent.name,
QuestRendererComponent.name,
EntityInfoComponent.name,
ScriptEditorComponent.name,
],
DEFAULT_LAYOUT_CONFIG
);
this.layout.registerComponent("QuestInfoComponent", QuestInfoComponent);
this.layout.registerComponent("QuestRendererComponent", QuestRendererComponent);
this.layout.registerComponent("EntityInfoComponent", EntityInfoComponent);
this.layout.registerComponent("ScriptEditorComponent", ScriptEditorComponent);
try {
this.layout = new GoldenLayout(config, this.layout_element.current);
} catch (e) {
logger.warn("Couldn't initialize golden layout with persisted layout.", e);
this.layout = new GoldenLayout(
DEFAULT_LAYOUT_CONFIG,
this.layout_element.current
);
}
this.layout.registerComponent(QuestInfoComponent.name, QuestInfoComponent);
this.layout.registerComponent(QuestRendererComponent.name, QuestRendererComponent);
this.layout.registerComponent(EntityInfoComponent.name, EntityInfoComponent);
this.layout.registerComponent(ScriptEditorComponent.name, ScriptEditorComponent);
this.layout.on("stateChanged", () => {
if (this.layout) {
quest_editor_ui_persister.persist_layout_config(this.layout.toConfig());
}
});
this.layout.init();
}
}, 0);

View File

@ -22,7 +22,6 @@ export class Toolbar extends Component {
overlay={
<Menu onClick={this.new_quest}>
<Menu.Item key={Episode[Episode.I]}>Episode I</Menu.Item>
<Menu.Item key={Episode[Episode.II]}>Episode II</Menu.Item>
<Menu.Item key={Episode[Episode.IV]}>Episode IV</Menu.Item>
</Menu>
}