Skip to content

Commit

Permalink
✨ styled html dialog component (#127)
Browse files Browse the repository at this point in the history
  • Loading branch information
haliphax authored Nov 12, 2024
1 parent f8427bb commit 305b2c9
Show file tree
Hide file tree
Showing 7 changed files with 161 additions and 18 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
"tab",
{
"ignoredNodes": ["PropertyDefinition"],
"offsetTernaryExpressions": true
"offsetTernaryExpressions": true,
"SwitchCase": 1
}
],
"vue/multi-word-component-names": "off"
Expand Down
3 changes: 3 additions & 0 deletions src/front-end/app/app.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
<script lang="ts">
import { defineComponent } from "vue";
import DarkMode from "./components/darkmode.vue";
import Dialogs from "./components/dialogs.vue";
import { ROOT_URI } from "./constants";
const App = defineComponent({
components: {
DarkMode,
Dialogs,
},
async beforeCreate() {
document.cookie = [
Expand All @@ -21,6 +23,7 @@ export default App;
</script>

<template>
<Dialogs></Dialogs>
<a class="btn ⏩" href="#main">
<span aria-hidden="true">⏩</span>
Skip to main
Expand Down
2 changes: 1 addition & 1 deletion src/front-end/app/components/darkmode.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const DarkMode = defineComponent({
created() {
this.bodyClass(this.enabled);
this.$store.subscribe((mutation) => {
const keys = Object.getOwnPropertyNames(mutation.payload);
const keys = Object.getOwnPropertyNames(mutation.payload ?? {});
if (mutation.type == "session" && keys.includes("settings"))
this.enabled = (mutation.payload as SessionState).settings.darkMode;
Expand Down
106 changes: 106 additions & 0 deletions src/front-end/app/components/dialogs.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<script lang="ts">
import { defineComponent } from "vue";
import { Module } from "vuex";
import { StoreState } from "../store/types";
type DialogsModuleState = object;
const dialogsModule: Module<DialogsModuleState, StoreState> = {
actions: {
alert() {},
confirm() {},
confirmed() {},
},
};
const Dialogs = defineComponent({
data() {
return {
responseId: "",
dialogText: "",
};
},
mounted() {
if (!this.$store.hasModule("dialogs")) {
this.$store.registerModule("dialogs", dialogsModule);
}
this.$store.subscribeAction((a) => {
switch (a.type) {
case "alert": {
this.responseId = a.payload.id ?? "";
this.dialogText = a.payload.text;
(this.$refs.alert as HTMLDialogElement).showModal();
break;
}
case "confirm": {
this.responseId = a.payload.id;
this.dialogText = a.payload.text;
(this.$refs.confirm as HTMLDialogElement).showModal();
break;
}
}
});
(this.$refs.alert as HTMLDialogElement).addEventListener(
"close",
async () => await this.$store.dispatch("close", this.responseId),
);
},
methods: {
async confirmed() {
(this.$refs.confirm as HTMLDialogElement).close("OK");
await this.$store.dispatch("confirmed", this.responseId);
},
},
});
export default Dialogs;
</script>

<template>
<span>
<dialog ref="alert">
<form method="dialog">
<fieldset>
<legend>Alert</legend>
<p>{{ dialogText }}</p>
<div>
<button class="fr" type="submit">✅ OK</button>
</div>
</fieldset>
</form>
</dialog>
<dialog ref="confirm">
<form method="dialog">
<fieldset>
<legend>Confirm</legend>
<p>{{ dialogText }}</p>
<div>
<button type="submit" value="Cancel">🚫 Cancel</button>
<button class="fr" value="OK" @click.prevent="confirmed">
✅ OK
</button>
</div>
</fieldset>
</form>
</dialog>
</span>
</template>

<style lang="less">
dialog {
background-color: var(--color-bg-global);
border: 1px solid #000;
color: var(--color-fg-global);
margin: auto;
max-width: 40rem;
padding: var(--space-l);
width: 100%;
}
dialog::backdrop {
backdrop-filter: blur(8px);
background-color: rgba(0, 0, 0, 0.2);
}
</style>
42 changes: 32 additions & 10 deletions src/front-end/app/views/home/profile.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,29 +27,51 @@ const Profile = defineComponent({
(this.$refs.file as HTMLInputElement).click();
},
async loadFile() {
const files = (this.$refs.file as HTMLInputElement).files;
const input = this.$refs.file as HTMLInputElement;
const files = input.files;
if (!files || files.length === 0) return;
if (files.length > 1) return alert("Please select a single file");
if (files.length > 1) {
input.value = "";
await this.$store.dispatch("alert", {
text: "Please select a single file",
});
return;
}
const file = files[0];
if (!file.name.endsWith(".json"))
return alert("Please select a JSON file");
if (!file.name.endsWith(".json")) {
input.value = "";
await this.$store.dispatch("alert", {
text: "Please select a JSON file",
});
return;
}
try {
const session: SessionState = JSON.parse(await file.text());
const session: SessionState = JSON.parse(await file.text());
this.$store.commit("session", session);
this.name = session.name;
} catch (ex) {
await this.$store.dispatch("alert", { text: `Error: ${ex}` });
} finally {
input.value = "";
}
this.$store.commit("session", session);
this.name = session.name;
requestAnimationFrame(() => {
requestAnimationFrame(async () => {
this.upToDate = true;
alert("Profile imported successfully");
await this.$store.dispatch("alert", {
text: "Profile imported successfully",
});
});
},
submit() {
this.$store.commit("session", { name: this.name });
this.upToDate = true;
alert("Profile updated");
this.$store.dispatch("alert", { text: "Profile updated" });
},
},
});
Expand Down
19 changes: 13 additions & 6 deletions src/front-end/app/views/story/actions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,29 @@
import { defineComponent } from "vue";
const Actions = defineComponent({
async mounted() {
this.$store.subscribeAction(async (a) => {
if (!(a.type === "confirmed" && a.payload === "reveal")) {
return;
}
await this.$store.dispatch("story.reveal");
});
},
methods: {
async copyUrl() {
await window.navigator.clipboard.writeText(window.location.href);
alert("The room URL has been copied to your clipboard!");
await this.$store.dispatch("alert", {
text: "The room URL has been copied to your clipboard!",
});
},
async reveal() {
const message =
this.$store.state.story.story?.owner === this.$store.state.session.id
? "Are you ready to reveal the votes?"
: "You are not the owner of this story. Are you sure?";
if (!confirm(message)) {
return;
}
await this.$store.dispatch("story.reveal");
await this.$store.dispatch("confirm", { id: "reveal", text: message });
},
},
});
Expand Down
4 changes: 4 additions & 0 deletions src/front-end/styles/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,10 @@ summary {
display: none;
}

.fr {
float: right;
}

.r {
text-align: right;
}
Expand Down

0 comments on commit 305b2c9

Please sign in to comment.