Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tab Cycling #177

Merged
merged 23 commits into from
Sep 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
f5cc516
First setup improved tabindexing
Lakeyzer Aug 4, 2023
0c609fe
Merge branch 'develop' into feature/tab_cycling
Lakeyzer Aug 4, 2023
5ffe0f1
In out of turn damage, focus on done-by-select input
Lakeyzer Aug 4, 2023
288fc94
Roll actions and spells with space when focused
Lakeyzer Aug 4, 2023
4d5c673
Autofocus action rolls and apply on enter
Lakeyzer Aug 4, 2023
a10a1da
Increase focus visibility for some elements
Lakeyzer Aug 5, 2023
568611d
Show correct options for multiple targets in Targeted.vue
Lakeyzer Aug 5, 2023
9393cb7
Fix damage on transformed entities
Lakeyzer Aug 25, 2023
d0c53db
Tab cycle condition selection
Lakeyzer Aug 25, 2023
a8312ef
Fix focus for action rolls
Lakeyzer Sep 1, 2023
da96d91
Index removed from action roll title
Lakeyzer Sep 1, 2023
44b1b0c
Autofocus removed from manual input
Lakeyzer Sep 1, 2023
543b349
Show keybind component created
Lakeyzer Sep 1, 2023
151f754
Tab cycling on set initiative
Lakeyzer Sep 1, 2023
e1fb5af
Fix outline overflow in set-initiative screen
Lakeyzer Sep 8, 2023
de6f51d
Autofocus input on out of turn damage/healing
Lakeyzer Sep 8, 2023
c81797e
Clear notifications on esc
Lakeyzer Sep 8, 2023
822a4f9
Fix focus on spell cast button
Lakeyzer Sep 29, 2023
67a45b8
Fix tab cycling for reminders
Lakeyzer Sep 29, 2023
4fe487f
Fix focus on actions and spells
Lakeyzer Sep 29, 2023
efce17f
Fix tab cycling for setting saving throws
Lakeyzer Sep 29, 2023
8e03631
Remove invalid keybind from overview
Lakeyzer Sep 29, 2023
5e3013f
Merge branch 'develop' into feature/tab_cycling
Lakeyzer Sep 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
<div v-if="slide.show == true" class="slide">
<a @click="hideSlide()" v-shortkey="['esc']" @shortkey="hideSlide()" class="hide">
<i aria-hidden="true" class="far fa-chevron-double-right" />
<span class="neutral-2 ml-2 d-none d-sm-inline">[esc]</span>
<hk-show-keybind class="neutral-2 ml-2 d-none d-sm-inline" :binds="['esc']" />
<q-tooltip anchor="bottom middle" self="center middle"> Hide [esc] </q-tooltip>
</a>
<div class="content" :class="slide.classes">
Expand Down Expand Up @@ -241,7 +241,7 @@ export default {
slide: "getSlide",
storeBroadcast: "broadcast",
}),
...mapGetters(["initialized", "theme", "user"]),
...mapGetters(["initialized", "theme", "user", "action_rolls"]),
announcement: {
get() {
const announcement = this.user && !this.announcement_cookie ? true : false;
Expand Down
2 changes: 2 additions & 0 deletions src/boot/hk-components.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import HkTable from "../components/hk-components/hk-table";
import HkCard from "../components/hk-components/hk-card";
import HkCardDeck from "../components/hk-components/hk-card-deck";
import HkShowKeybind from "../components/hk-components/hk-show-keybind";
import HkRoll from "../components/hk-components/hk-roll";
import HkRollAction from "../components/hk-components/hk-action-rolls/hk-roll-action";
import HkAnimatedInteger from "../components/hk-components/hk-animated-integer";
Expand All @@ -24,6 +25,7 @@ export default async ({ Vue }) => {
Vue.component("hk-table", HkTable);
Vue.component("hk-card", HkCard);
Vue.component("hk-card-deck", HkCardDeck);
Vue.component("hk-show-keybind", HkShowKeybind);
Vue.component("hk-animated-integer", HkAnimatedInteger);
Vue.component("hk-roll", HkRoll);
Vue.component("hk-roll-action", HkRollAction);
Expand Down
214 changes: 137 additions & 77 deletions src/components/Header.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,35 @@
<template>
<header>
<div id="header" class="d-flex justify-content-between items-center" :class="{ 'hidden-sidebar': $route.meta.sidebar === false }">
<div
id="header"
class="d-flex justify-content-between items-center"
:class="{ 'hidden-sidebar': $route.meta.sidebar === false }"
>
<div>
<div
class="menu"
@click.stop="setSideSmallScreen(!$store.getters.side_small_screen)"
>
<i aria-hidden="true" class="fas" :class="$store.getters.side_small_screen ? 'fa-times' : 'fa-bars'"/>
<div class="menu" @click.stop="setSideSmallScreen(!$store.getters.side_small_screen)">
<i
aria-hidden="true"
class="fas"
:class="$store.getters.side_small_screen ? 'fa-times' : 'fa-bars'"
/>
</div>
<router-link to="/" class="logo d-flex justify-content-start" :class="{ home: $route.meta.sidebar === false }">
<img class="icon" src="../assets/_img/logo/logo-icon-cyan.svg" alt="logo icon" :class="{ 'd-none d-md-block': environment !== 'live' }" />
<img class="wordmark d-none d-md-block" src="../assets/_img/logo/logo-wordmark.svg" alt="Harmless Key"/>
<router-link
to="/"
class="logo d-flex justify-content-start"
:class="{ home: $route.meta.sidebar === false }"
:tabindex="tabindex"
>
<img
class="icon"
src="../assets/_img/logo/logo-icon-cyan.svg"
alt="logo icon"
:class="{ 'd-none d-md-block': environment !== 'live' }"
/>
<img
class="wordmark d-none d-md-block"
src="../assets/_img/logo/logo-wordmark.svg"
alt="Harmless Key"
/>
</router-link>
</div>

Expand All @@ -21,49 +40,71 @@

<div class="d-flex justify-content-end">
<div class="area d-flex justify-content-end" :class="{ 'mr-2': maintenance }">
<button class="icon" aria-label="Select theme">
<i aria-hidden="true" class="fas fa-moon"/>
<button class="icon" aria-label="Select theme" :tabindex="tabindex">
<i aria-hidden="true" class="fas fa-moon" />
<q-popup-proxy :dark="$store.getters.theme === 'dark'" :offset="[9, 0]">
<div class="theme">
<button @click="setTheme('dark')" :class="{ active: $store.getters.theme === 'dark' }" aria-label="Dark theme">
<button
@click="setTheme('dark')"
:class="{ active: $store.getters.theme === 'dark' }"
aria-label="Dark theme"
>
<img src="~assets/_img/dark.webp" alt="Dark theme" />
Dark
</button>
<button @click="setTheme('light')" :class="{ active: $store.getters.theme === 'light' }" aria-label="Light theme">
<button
@click="setTheme('light')"
:class="{ active: $store.getters.theme === 'light' }"
aria-label="Light theme"
>
<img src="~assets/_img/light.webp" alt="Light theme" />
Light
</button>
</div>
</q-popup-proxy>
</button>
<button class="icon d-none d-md-block" aria-label="Keybindings"
@click="setSlide({show: true, type: 'slides/Keybindings', data: {sm: true}})">
<i aria-hidden="true" class="fas fa-keyboard"/>
<button
class="icon d-none d-md-block"
aria-label="Keybindings"
:tabindex="tabindex"
@click="setSlide({ show: true, type: 'slides/Keybindings', data: { sm: true } })"
>
<i aria-hidden="true" class="fas fa-keyboard" />
<q-tooltip anchor="bottom middle" self="top middle" :offset="[0, 10]">
Keybindings
</q-tooltip>
</button>
<button class="icon" aria-label="Compendium"
@click="setSlide({show: true, type: 'slides/Compendium'})">
<button
class="icon"
aria-label="Compendium"
:tabindex="tabindex"
@click="setSlide({ show: true, type: 'slides/Compendium' })"
>
<i aria-hidden="true" class="fas fa-book-spells"></i>
<q-tooltip anchor="bottom middle" self="top middle" :offset="[0, 10]">
Compendium
</q-tooltip>
</button>
<button
<button
v-if="user && !maintenance"
aria-label="Live initiative link"
class="icon"
@click="setSlide({show: true, type: 'PlayerLink'})">
:tabindex="tabindex"
@click="setSlide({ show: true, type: 'PlayerLink' })"
>
<i aria-hidden="true" class="fas fa-share-alt"></i>
<q-tooltip anchor="bottom middle" self="top middle" :offset="[0, 10]">
Public initiative
</q-tooltip>
</button>
<button class="icon roll"
<button
class="icon roll"
aria-label="Dice roller"
v-shortkey="['r']" @shortkey="setSlide({show: true, type: 'slides/roll/index'})"
@click="setSlide({show: true, type: 'slides/roll/index'})">
v-shortkey="['r']"
:tabindex="tabindex"
@shortkey="setSlide({ show: true, type: 'slides/roll/index' })"
@click="setSlide({ show: true, type: 'slides/roll/index' })"
>
<q-tooltip anchor="bottom middle" self="top middle" :offset="[0, 10]">
Dice roller
</q-tooltip>
Expand All @@ -72,34 +113,55 @@
<template v-if="!maintenance">
<q-separator vertical :dark="$store.getters.theme === 'dark'" inset class="mx-1" />
<div v-if="user" class="user">
<span class="img" v-if="user.photoURL" :style="{'background-image': 'url(' + user.photoURL + ')'}"></span>
<span
class="img"
v-if="user.photoURL"
:style="{ 'background-image': 'url(' + user.photoURL + ')' }"
></span>
<i aria-hidden="true" v-else class="fas fa-user"></i>
<q-popup-proxy :dark="$store.getters.theme === 'dark'" :offset="[9, 0]">
<div class="bg-neutral-8">
<q-list>
<q-item clickable v-close-popup to="/admin" v-if="userInfo && userInfo.admin">
<q-item-section avatar><i aria-hidden="true" class="fas fa-crown"></i></q-item-section>
<q-item-section avatar
><i aria-hidden="true" class="fas fa-crown"></i
></q-item-section>
<q-item-section>Admin</q-item-section>
</q-item>
<q-item clickable v-close-popup to="/contribute" v-if="userInfo && (userInfo.admin || userInfo.contribute)">
<q-item-section avatar><i aria-hidden="true" class="fas fa-file-edit"></i></q-item-section>
<q-item
clickable
v-close-popup
to="/contribute"
v-if="userInfo && (userInfo.admin || userInfo.contribute)"
>
<q-item-section avatar
><i aria-hidden="true" class="fas fa-file-edit"></i
></q-item-section>
<q-item-section>Contribute</q-item-section>
</q-item>
<q-item clickable v-close-popup to="/profile">
<q-item-section avatar><i aria-hidden="true" class="fas fa-user"></i></q-item-section>
<q-item-section avatar
><i aria-hidden="true" class="fas fa-user"></i
></q-item-section>
<q-item-section>Profile</q-item-section>
</q-item>
<q-item clickable v-close-popup to="/content">
<q-item-section avatar><i aria-hidden="true" class="fas fa-treasure-chest"></i></q-item-section>
<q-item-section avatar
><i aria-hidden="true" class="fas fa-treasure-chest"></i
></q-item-section>
<q-item-section>My content</q-item-section>
</q-item>
<q-item clickable v-close-popup to="/content/settings">
<q-item-section avatar><i aria-hidden="true" class="fas fa-cogs"></i></q-item-section>
<q-item-section avatar
><i aria-hidden="true" class="fas fa-cogs"></i
></q-item-section>
<q-item-section>Settings</q-item-section>
</q-item>
<q-separator />
<q-item clickable v-close-popup @click="signOut()">
<q-item-section avatar><i aria-hidden="true" class="fas fa-sign-out-alt"></i></q-item-section>
<q-item-section avatar
><i aria-hidden="true" class="fas fa-sign-out-alt"></i
></q-item-section>
<q-item-section>Sign out</q-item-section>
</q-item>
</q-list>
Expand All @@ -114,46 +176,41 @@
</template>

<script>
import { mapActions, mapGetters } from 'vuex';
import { mapActions, mapGetters } from "vuex";

export default {
name: "Header",
props: {
maintenance: {
type: [Boolean, String],
default: false
}
export default {
name: "Header",
props: {
maintenance: {
type: [Boolean, String],
default: false,
},
data() {
return {
environment: process.env.VUE_APP_ENV_NAME
}
},
data() {
return {
environment: process.env.VUE_APP_ENV_NAME,
};
},
computed: {
...mapGetters(["user", "userInfo"]),
tabindex() {
return this.$route.name === "RunEncounter" ? -1 : 0;
},
computed: {
...mapGetters([
'user',
'userInfo'
]),
},
methods: {
...mapActions(["setSlide", "setSideSmallScreen", "setTheme", "sign_out"]),
showSlide(type) {
this.setSlide({
show: true,
type,
});
},
methods: {
...mapActions([
'setSlide',
'setSideSmallScreen',
'setTheme',
'sign_out'
]),
showSlide(type) {
this.setSlide({
show: true,
type,
})
},
signOut() {
if(this.$route.path !== "/") this.$router.replace('/');
this.sign_out();
}
}
};
signOut() {
if (this.$route.path !== "/") this.$router.replace("/");
this.sign_out();
},
},
};
</script>

<style lang="scss" scoped>
Expand All @@ -171,7 +228,7 @@
left: 5px;
top: 5px;
height: 40px;
transition: position .4s linear;
transition: position 0.4s linear;

.icon {
height: 40px;
Expand All @@ -181,7 +238,8 @@
height: 13px;
}
}
a.icon, button.icon {
a.icon,
button.icon {
cursor: pointer;
font-size: 18px;
text-align: center;
Expand All @@ -199,7 +257,7 @@ a.icon, button.icon {
}
&.roll {
margin-left: 5px;
background-image: url('../assets/_img/logo/logo-icon-no-shield-gray-no-border.svg');
background-image: url("../assets/_img/logo/logo-icon-no-shield-gray-no-border.svg");
background-size: 22px 22px;
background-position: center;
background-repeat: no-repeat;
Expand All @@ -224,7 +282,8 @@ a.icon, button.icon {
padding: 3px;
color: $neutral-3;

&:hover, &.active {
&:hover,
&.active {
border-color: $blue;
color: $neutral-1;
}
Expand All @@ -234,12 +293,12 @@ a.icon, button.icon {
}
}
}
.user {
.user {
cursor: pointer;
font-size: 15px;
padding: 12px 15px 12px 10px;
line-height: 26px !important;
height: 50px ;
height: 50px;
display: block;

.img {
Expand Down Expand Up @@ -270,10 +329,11 @@ a.icon, button.icon {
width: 41px;
padding: 0 10px;
}
a.icon, button.icon {
a.icon,
button.icon {
font-size: 25px;
width: 30px;

&.roll {
padding-left: 30px;
background-size: 27px 27px;
Expand All @@ -292,7 +352,7 @@ a.icon, button.icon {
}
[data-theme="light"] {
a.icon.roll {
background-image: url('../assets/_img/logo/logo-icon-no-shield-gray-dark-no-border.svg');
background-image: url("../assets/_img/logo/logo-icon-no-shield-gray-dark-no-border.svg");
}
}
</style>
</style>
Loading
Loading