mirror of
https://github.com/DaanVandenBosch/phantasmal-world.git
synced 2025-04-05 07:18:29 +08:00
Quest editor layout is now persisted.
This commit is contained in:
parent
25b7a4869b
commit
52376193ae
@ -1,6 +1,8 @@
|
|||||||
import { Persister } from "./Persister";
|
import { Persister } from "./Persister";
|
||||||
import { Server, HuntMethod } from "../domain";
|
import { Server, HuntMethod } from "../domain";
|
||||||
|
|
||||||
|
const METHOD_USER_TIMES_KEY = "HuntMethodStore.methodUserTimes";
|
||||||
|
|
||||||
class HuntMethodPersister extends Persister {
|
class HuntMethodPersister extends Persister {
|
||||||
persist_method_user_times(hunt_methods: HuntMethod[], server: Server): void {
|
persist_method_user_times(hunt_methods: HuntMethod[], server: Server): void {
|
||||||
const user_times: PersistedUserTimes = {};
|
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(
|
async load_method_user_times(
|
||||||
@ -20,7 +22,7 @@ class HuntMethodPersister extends Persister {
|
|||||||
): Promise<HuntMethod[]> {
|
): Promise<HuntMethod[]> {
|
||||||
const user_times = await this.load_for_server<PersistedUserTimes>(
|
const user_times = await this.load_for_server<PersistedUserTimes>(
|
||||||
server,
|
server,
|
||||||
"HuntMethodStore.methodUserTimes"
|
METHOD_USER_TIMES_KEY
|
||||||
);
|
);
|
||||||
|
|
||||||
if (user_times) {
|
if (user_times) {
|
||||||
|
@ -3,11 +3,13 @@ import { WantedItem } from "../stores/HuntOptimizerStore";
|
|||||||
import { item_type_stores } from "../stores/ItemTypeStore";
|
import { item_type_stores } from "../stores/ItemTypeStore";
|
||||||
import { Persister } from "./Persister";
|
import { Persister } from "./Persister";
|
||||||
|
|
||||||
|
const WANTED_ITEMS_KEY = "HuntOptimizerStore.wantedItems";
|
||||||
|
|
||||||
class HuntOptimizerPersister extends Persister {
|
class HuntOptimizerPersister extends Persister {
|
||||||
persist_wanted_items(server: Server, wanted_items: WantedItem[]): void {
|
persist_wanted_items(server: Server, wanted_items: WantedItem[]): void {
|
||||||
this.persist_for_server(
|
this.persist_for_server(
|
||||||
server,
|
server,
|
||||||
"HuntOptimizerStore.wantedItems",
|
WANTED_ITEMS_KEY,
|
||||||
wanted_items.map(
|
wanted_items.map(
|
||||||
({ item_type, amount }): PersistedWantedItem => ({
|
({ item_type, amount }): PersistedWantedItem => ({
|
||||||
itemTypeId: item_type.id,
|
itemTypeId: item_type.id,
|
||||||
@ -22,7 +24,7 @@ class HuntOptimizerPersister extends Persister {
|
|||||||
|
|
||||||
const persisted_wanted_items = await this.load_for_server<PersistedWantedItem[]>(
|
const persisted_wanted_items = await this.load_for_server<PersistedWantedItem[]>(
|
||||||
server,
|
server,
|
||||||
"HuntOptimizerStore.wantedItems"
|
WANTED_ITEMS_KEY
|
||||||
);
|
);
|
||||||
const wanted_items: WantedItem[] = [];
|
const wanted_items: WantedItem[] = [];
|
||||||
|
|
||||||
|
57
src/persistence/QuestEditorUiPersister.ts
Normal file
57
src/persistence/QuestEditorUiPersister.ts
Normal 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();
|
@ -38,7 +38,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
overflow: hidden;
|
overflow: hidden; // Necessary for golden layout.
|
||||||
}
|
}
|
||||||
|
|
||||||
// react-virtualized
|
// react-virtualized
|
||||||
|
@ -9,6 +9,64 @@ import { QuestInfoComponent } from "./QuestInfoComponent";
|
|||||||
import { QuestRendererComponent } from "./QuestRendererComponent";
|
import { QuestRendererComponent } from "./QuestRendererComponent";
|
||||||
import { ScriptEditorComponent } from "./ScriptEditorComponent";
|
import { ScriptEditorComponent } from "./ScriptEditorComponent";
|
||||||
import { Toolbar } from "./Toolbar";
|
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
|
@observer
|
||||||
export class QuestEditorComponent extends Component {
|
export class QuestEditorComponent extends Component {
|
||||||
@ -20,68 +78,39 @@ export class QuestEditorComponent extends Component {
|
|||||||
|
|
||||||
window.addEventListener("resize", this.resize);
|
window.addEventListener("resize", this.resize);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(async () => {
|
||||||
if (this.layout_element.current && !this.layout) {
|
if (this.layout_element.current && !this.layout) {
|
||||||
this.layout = new GoldenLayout(
|
const config = await quest_editor_ui_persister.load_layout_config(
|
||||||
{
|
[
|
||||||
settings: {
|
QuestInfoComponent.name,
|
||||||
showPopoutIcon: false,
|
QuestRendererComponent.name,
|
||||||
},
|
EntityInfoComponent.name,
|
||||||
dimensions: {
|
ScriptEditorComponent.name,
|
||||||
headerHeight: 28,
|
],
|
||||||
},
|
DEFAULT_LAYOUT_CONFIG
|
||||||
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
|
|
||||||
);
|
);
|
||||||
this.layout.registerComponent("QuestInfoComponent", QuestInfoComponent);
|
|
||||||
this.layout.registerComponent("QuestRendererComponent", QuestRendererComponent);
|
try {
|
||||||
this.layout.registerComponent("EntityInfoComponent", EntityInfoComponent);
|
this.layout = new GoldenLayout(config, this.layout_element.current);
|
||||||
this.layout.registerComponent("ScriptEditorComponent", ScriptEditorComponent);
|
} 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();
|
this.layout.init();
|
||||||
}
|
}
|
||||||
}, 0);
|
}, 0);
|
||||||
|
@ -22,7 +22,6 @@ export class Toolbar extends Component {
|
|||||||
overlay={
|
overlay={
|
||||||
<Menu onClick={this.new_quest}>
|
<Menu onClick={this.new_quest}>
|
||||||
<Menu.Item key={Episode[Episode.I]}>Episode I</Menu.Item>
|
<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.Item key={Episode[Episode.IV]}>Episode IV</Menu.Item>
|
||||||
</Menu>
|
</Menu>
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user