Skip to content

Commit 50556f7

Browse files
authored
client: refactor more components to use setup to simplify them (part 3) (#1595)
1 parent 7737d8c commit 50556f7

File tree

6 files changed

+289
-400
lines changed

6 files changed

+289
-400
lines changed

client/src/components/ClickToEdit.vue

+51-77
Original file line numberDiff line numberDiff line change
@@ -20,93 +20,67 @@
2020
</div>
2121
</template>
2222

23-
<script lang="ts">
24-
import { defineComponent, ref, nextTick, Ref } from "vue";
25-
26-
function valueFormatterDefault(value: number): string {
27-
return value.toString();
28-
}
29-
30-
function valueParserDefault(value: string): number {
31-
return parseInt(value, 10);
32-
}
33-
23+
<script lang="ts" setup generic="T extends string | number">
3424
/**
3525
* Provides a value display that can be clicked to edit.
3626
*/
37-
const ClickToEdit = defineComponent({
38-
name: "ClickToEdit",
39-
emits: ["change", "update:modelValue"],
40-
props: {
41-
modelValue: {
42-
type: [String, Number],
43-
required: true,
44-
},
45-
valueFormatter: {
46-
type: Function,
47-
default: valueFormatterDefault,
48-
},
49-
valueParser: {
50-
type: Function,
51-
default: valueParserDefault,
52-
},
53-
},
54-
setup(props, { emit }) {
55-
const editor = ref<HTMLInputElement | undefined>();
56-
const valueFormatter = ref(props.valueFormatter) as Ref<(value: number) => string>;
57-
const valueParser = ref(props.valueParser) as Ref<(value: string) => number>;
27+
import { ref, nextTick, Ref } from "vue";
5828
59-
const editing = ref(false);
60-
const valueDirty = ref();
61-
const display: Ref<HTMLDivElement | undefined> = ref();
62-
const editorWidth = ref(120);
29+
const props = withDefaults(
30+
defineProps<{
31+
valueFormatter?: (value: number) => string;
32+
valueParser?: (value: string) => number;
33+
}>(),
34+
{
35+
valueFormatter: (value: number): string => value.toString(),
36+
valueParser: (value: string): number => parseInt(value, 10),
37+
}
38+
);
6339
64-
async function activate() {
65-
if (display.value) {
66-
editorWidth.value = display.value.offsetWidth + 24;
67-
}
68-
console.info("modelValue", props.modelValue);
69-
if (typeof props.modelValue === "number") {
70-
valueDirty.value = valueFormatter.value(props.modelValue);
71-
} else {
72-
valueDirty.value = props.modelValue;
73-
}
74-
editing.value = true;
75-
await nextTick();
76-
editor.value?.focus();
77-
}
40+
const model = defineModel<T>();
7841
79-
function apply() {
80-
let outValue: string | number;
81-
if (typeof props.modelValue === "number") {
82-
outValue = valueParser.value(valueDirty.value);
83-
} else {
84-
outValue = valueDirty.value;
85-
}
86-
editing.value = false;
87-
emit("change", outValue);
88-
emit("update:modelValue", outValue);
89-
}
42+
const emit = defineEmits<{
43+
change: [value: T];
44+
}>();
9045
91-
function abort() {
92-
editing.value = false;
93-
}
46+
const editor = ref<HTMLInputElement | undefined>();
47+
const valueFormatter = ref(props.valueFormatter) as Ref<(value: number) => string>;
48+
const valueParser = ref(props.valueParser) as Ref<(value: string) => number>;
9449
95-
return {
96-
editor,
97-
display,
98-
editing,
99-
valueDirty,
100-
editorWidth,
50+
const editing = ref(false);
51+
const valueDirty = ref("");
52+
const display: Ref<HTMLDivElement | undefined> = ref();
53+
const editorWidth = ref(120);
10154
102-
activate,
103-
apply,
104-
abort,
105-
};
106-
},
107-
});
55+
async function activate() {
56+
if (display.value) {
57+
editorWidth.value = display.value.offsetWidth + 24;
58+
}
59+
if (typeof model.value === "number") {
60+
valueDirty.value = valueFormatter.value(model.value);
61+
} else {
62+
valueDirty.value = model.value ?? "";
63+
}
64+
editing.value = true;
65+
await nextTick();
66+
editor.value?.focus();
67+
}
68+
69+
function apply() {
70+
let outValue: T;
71+
if (typeof model.value === "number") {
72+
outValue = valueParser.value(valueDirty.value) as T;
73+
} else {
74+
outValue = valueDirty.value as T;
75+
}
76+
editing.value = false;
77+
model.value = outValue;
78+
emit("change", outValue);
79+
}
10880
109-
export default ClickToEdit;
81+
function abort() {
82+
editing.value = false;
83+
}
11084
</script>
11185

11286
<style lang="scss">

client/src/components/ClientSettingsDialog.vue

+30-47
Original file line numberDiff line numberDiff line change
@@ -50,19 +50,19 @@
5050

5151
<v-card-actions>
5252
<v-spacer />
53-
<v-btn color="primary" text @click="applySettings">
53+
<v-btn color="primary" @click="applySettings">
5454
{{ $t("common.save") }}
5555
</v-btn>
56-
<v-btn text @click="cancelSettings">
56+
<v-btn @click="cancelSettings">
5757
{{ $t("common.cancel") }}
5858
</v-btn>
5959
</v-card-actions>
6060
</v-card>
6161
</v-dialog>
6262
</template>
6363

64-
<script lang="ts">
65-
import { defineComponent, Ref, ref, watch } from "vue";
64+
<script lang="ts" setup>
65+
import { Ref, ref, watch } from "vue";
6666
import { useStore } from "@/store";
6767
import { SettingsState, RoomLayoutMode, Theme } from "@/stores/settings";
6868
import _ from "lodash";
@@ -73,54 +73,37 @@ type ExcludedFields = "volume" | "locale";
7373
type ExposedSettings = Omit<SettingsState, ExcludedFields>;
7474
const EXCLUDED: ExcludedFields[] = ["volume", "locale"];
7575
76-
export const ClientSettingsDialog = defineComponent({
77-
name: "ClientSettingsDialog",
78-
setup() {
79-
const show = ref(false);
80-
const store = useStore();
81-
const settings: Ref<ExposedSettings> = ref(loadSettings());
82-
const sfx = useSfx();
76+
const show = ref(false);
77+
const store = useStore();
78+
const settings: Ref<ExposedSettings> = ref(loadSettings());
79+
const sfx = useSfx();
8380
84-
function loadSettings(): ExposedSettings {
85-
const copy = _.cloneDeep(store.state.settings);
86-
const filtered = _.omit(copy, EXCLUDED);
87-
return filtered;
88-
}
81+
function loadSettings(): ExposedSettings {
82+
const copy = _.cloneDeep(store.state.settings);
83+
const filtered = _.omit(copy, EXCLUDED);
84+
return filtered;
85+
}
8986
90-
function applySettings() {
91-
store.commit("settings/UPDATE", settings.value);
92-
show.value = false;
93-
}
87+
function applySettings() {
88+
store.commit("settings/UPDATE", settings.value);
89+
show.value = false;
90+
}
9491
95-
function cancelSettings() {
96-
show.value = false;
97-
}
92+
function cancelSettings() {
93+
show.value = false;
94+
}
9895
99-
watch(show, () => {
100-
settings.value = loadSettings();
101-
});
102-
103-
store.subscribe(mutation => {
104-
if (mutation.type === "settings/UPDATE") {
105-
sfx.enabled = store.state.settings.sfxEnabled;
106-
sfx.volume.value = store.state.settings.sfxVolume;
107-
}
108-
});
109-
110-
return {
111-
show,
112-
settings,
113-
114-
applySettings,
115-
cancelSettings,
116-
RoomLayoutMode,
117-
Theme,
96+
watch(show, () => {
97+
settings.value = loadSettings();
98+
});
11899
119-
layouts: enumKeys(RoomLayoutMode),
120-
themes: enumKeys(Theme),
121-
};
122-
},
100+
store.subscribe(mutation => {
101+
if (mutation.type === "settings/UPDATE") {
102+
sfx.enabled = store.state.settings.sfxEnabled;
103+
sfx.volume.value = store.state.settings.sfxVolume;
104+
}
123105
});
124106
125-
export default ClientSettingsDialog;
107+
const layouts = enumKeys(RoomLayoutMode);
108+
const themes = enumKeys(Theme);
126109
</script>

0 commit comments

Comments
 (0)