Skip to content

Commit

Permalink
* replace props with typed props
Browse files Browse the repository at this point in the history
 * add vue-i18n linting
 * fix i18n linting errors
  • Loading branch information
ConorMurphy21 committed Feb 5, 2024
1 parent c1cf903 commit d9e7889
Show file tree
Hide file tree
Showing 23 changed files with 302 additions and 118 deletions.
17 changes: 13 additions & 4 deletions client/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ require('@rushstack/eslint-patch/modern-module-resolution');

module.exports = {
extends: [
'plugin:vue/vue3-essential',
'plugin:vue/vue3-strongly-recommended',
'plugin:vue/vue3-recommended',
'eslint:recommended',
'plugin:@intlify/vue-i18n/recommended',
'plugin:@typescript-eslint/recommended-type-checked',
'@vue/eslint-config-typescript',
'@vue/eslint-config-prettier/skip-formatting',
Expand All @@ -29,13 +28,23 @@ module.exports = {
'vue/component-api-style': [2, ['script-setup']],
'vue/block-lang': [2, { script: { lang: 'ts' } }],
'vue/define-macros-order': 2,
// 'vue/define-props-declaration': 2,
'vue/define-props-declaration': 2,
'vue/no-ref-object-reactivity-loss': 2,
'vue/no-undef-properties': 2,
'vue/no-unused-components': [2, { ignoreWhenBindingPresent: true }],
'vue/no-unused-properties': 2,
'vue/no-unused-refs': 2,
'@intlify/vue-i18n/valid-message-syntax': 2,
'@intlify/vue-i18n/key-format-style': [2, 'camelCase', {allowArray: true}],
'@intlify/vue-i18n/no-duplicate-keys-in-locale': 2,
'@intlify/vue-i18n/no-missing-keys-in-other-locales': 2,
'prettier/prettier': 2
},
ignorePatterns: ['/*', '!/src']
ignorePatterns: ['/*', '!/src'],
settings: {
'vue-i18n': {
localeDir: './src/locales/*.{ts}', // extension is glob formatting!
messageSyntaxVersion: '^9.9.1'
}
}
};
8 changes: 6 additions & 2 deletions client/src/components/endGame/EndGame.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const click = new AudioWrap(ClickMp3);
const gameStore = useGameStore();
const rank = computed((): number[] => {
const rank = computed<number[]>(() => {
let result = [];
let lastScore = -1;
let lastRank = 1;
Expand Down Expand Up @@ -39,7 +39,11 @@ const { n } = useI18n();

<div class="list-group w-75 w-xl-50">
<div v-for="(score, index) in gameStore.scores" :key="score.player.id" class="list-group-item">
{{ rank[index] }}. {{ score.player.name }}: {{ n(score.points) }}
<span
v-t="{
path: 'scoreFormat',
args: { rank: rank[index], player: score.player.name, points: n(score.points) }
}" />
</div>
</div>

Expand Down
2 changes: 1 addition & 1 deletion client/src/components/endRound/PlayerChooser.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const hoverLeft = ref(false);
const hoverRight = ref(false);
const model = defineModel({ type: String, required: true });
const selectedName = computed((): string => {
const selectedName = computed<string>(() => {
if (!model.value) return '';
const name = roomStore.players.find((player: Player) => player.id === model.value)?.name;
return name === undefined ? '' : name;
Expand Down
18 changes: 8 additions & 10 deletions client/src/components/gameShared/NotificationCount.vue
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
<script setup lang="ts">
import { computed } from 'vue';
const props = defineProps({
width: {
type: Number,
default: 24
},
nextMajority: {
type: Boolean,
default: false
}
interface Props {
width?: number;
nextMajority?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
width: 24,
nextMajority: false
});
const cssProps = computed((): Record<string, string> => {
const cssProps = computed<Record<string, string>>(() => {
return {
'--min-width': props.width + 'px'
};
Expand Down
21 changes: 9 additions & 12 deletions client/src/components/gameShared/Prompt.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,21 @@
import VoteSkip from '@/components/promptResponse/VoteSkip.vue';
import { computed } from 'vue';
const props = defineProps({
prompt: {
type: String,
required: true
},
skippable: {
type: Boolean,
default: false
}
interface Props {
prompt: string;
skippable?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
skippable: false
});
const containsBlank = computed((): boolean => {
const containsBlank = computed<boolean>(() => {
return props.prompt.includes('_');
});
const left = computed((): string => {
const left = computed<string>(() => {
return props.prompt.substring(0, props.prompt.indexOf('_'));
});
const right = computed((): string => {
const right = computed<string>(() => {
return props.prompt.substring(props.prompt.lastIndexOf('_') + 1);
});
</script>
Expand Down
31 changes: 13 additions & 18 deletions client/src/components/gameShared/ResponseList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,14 @@ import Click1Mp3 from '@/assets/audio/click1.mp3';
import Click2Mp3 from '@/assets/audio/click2.mp3';
import { useGameStore } from '@/stores/game.js';
const props = defineProps({
selectable: {
type: Boolean,
required: true
},
playerId: {
type: String,
default: ''
},
height: {
type: Number,
default: 30
}
interface Props {
selectable: boolean;
playerId?: string;
height?: number;
}
const props = withDefaults(defineProps<Props>(), {
playerId: '',
height: 30
});
const gameStore = useGameStore();
Expand All @@ -27,19 +22,19 @@ const model = defineModel({ type: String });
const selected = ref(-1);
const responses = computed((): string[] => {
const responses = computed<string[]>(() => {
return gameStore.playerResponses(props.playerId).all;
});
const usedResponses = computed((): string[] => {
const usedResponses = computed<string[]>(() => {
return gameStore.playerResponses(props.playerId).used;
});
const selectedStrike = computed((): string => {
const selectedStrike = computed<string>(() => {
return gameStore.playerResponses(props.playerId).selectedStrike;
});
const selectedSike = computed((): string => {
const selectedSike = computed<string>(() => {
return gameStore.playerResponses(props.playerId).selectedSike;
});
const cssProps = computed((): Record<string, string> => {
const cssProps = computed<Record<string, string>>(() => {
return {
'--max-height': props.height + 'vh'
};
Expand Down
12 changes: 6 additions & 6 deletions client/src/components/gameShared/SelectionType.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ import ChoiceImg from '@/assets/images/choice.png';
import { useGameStore } from '@/stores/game.js';
import { useI18n } from 'vue-i18n';
defineProps({
tooltip: {
type: Boolean,
default: true
}
interface Props {
tooltip?: boolean;
}
withDefaults(defineProps<Props>(), {
tooltip: true
});
const gameStore = useGameStore();
const typeImg = computed(() => {
const typeImg = computed<string>(() => {
if (gameStore.selectionType === 'strike') {
return StrikeImg;
} else if (gameStore.selectionType === 'sike') {
Expand Down
10 changes: 4 additions & 6 deletions client/src/components/gameShared/Timer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@ import timerMp3 from '@/assets/audio/timer_full.mp3';
import timerCompleteMp3 from '@/assets/audio/timerComplete.mp3';
import { useI18n } from 'vue-i18n';
defineProps({
time: {
type: Number,
required: true
}
});
defineProps<{
time: number;
}>();
const timer = new AudioWrap(timerMp3);
const timerComplete = new AudioWrap(timerCompleteMp3);
const gameStore = useGameStore();
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/gameShared/VolumeControl.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const settingsStore = useSettingsStore();
const showing = ref(false);
const timer: Ref<null | NodeJS.Timeout> = ref(null);
const value = computed({
const value = computed<number>({
get(): number {
return Math.round(settingsStore.volume * 100);
},
Expand Down
4 changes: 2 additions & 2 deletions client/src/components/lobby/Lobby.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import { useI18n } from 'vue-i18n';
const click = new AudioWrap(ClickMp3);
const roomStore = useRoomStore();
const leader = computed((): boolean => {
const leader = computed<boolean>(() => {
return !!roomStore.self && roomStore.self.leader;
});
const canStart = computed((): boolean => {
const canStart = computed<boolean>(() => {
return leader.value && roomStore.players.length >= 3;
});
Expand Down
14 changes: 5 additions & 9 deletions client/src/components/lobby/Options.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,9 @@ import { useGameStore } from '@/stores/game.js';
import { useI18n } from 'vue-i18n';
import { useRoomStore } from '@/stores/room.js';
defineProps({
disabled: {
type: Boolean,
required: true
}
});
defineProps<{
disabled: boolean;
}>();
const customSelected = ref(false);
const timerDuration: Ref<null | HTMLFormElement> = ref(null);
Expand Down Expand Up @@ -204,14 +201,13 @@ const { t } = useI18n();
</div>
<h2 id="options-heading" class="accordion-header">
<button
v-t="'optionsLabel'"
class="accordion-button"
type="button"
data-bs-toggle="collapse"
data-bs-target="#form"
aria-expanded="false"
aria-controls="form">
Game Options
</button>
aria-controls="form" />
</h2>
</div>
</div>
Expand Down
10 changes: 3 additions & 7 deletions client/src/components/lobby/PlayerCard.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
<script setup lang="ts">
import { type PropType } from 'vue';
import type { Player } from ':common/stateTypes.js';
defineProps({
player: {
type: Object as PropType<Player>,
required: true
}
});
defineProps<{
player: Player;
}>();
</script>

<template>
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/lobby/PlayerList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useRoomStore } from '@/stores/room.js';
const roomStore = useRoomStore();
const columns = computed((): [Player[], Player[]] => {
const columns = computed<[Player[], Player[]]>(() => {
const columns = [[], []] as [Player[], Player[]];
for (let i = 0; i < roomStore.players.length; i++) {
columns[i % 2].push(roomStore.players[i]);
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/responseMatching/ActiveMatching.vue
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ const { t } = useI18n();
<img class="my-auto w-75 w-sm-50 w-lg-25" src="@/assets/images/sike.png" :alt="t('sike')" />
</div>
</button>
or
<span v-t="'or'" />
<response-list v-model="matchedResponse" :selectable="true" :height="40" />
</div>
</template>
Expand Down
20 changes: 7 additions & 13 deletions client/src/components/responseMatching/DisputeIcon.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,13 @@ import socket from '@/socket/socket.js';
import { useI18n } from 'vue-i18n';
import { useGameStore } from '@/stores/game.js';
defineProps({
disabled: {
type: Boolean,
default: false
},
response: {
type: String,
required: true
},
placement: {
type: String,
required: true
}
interface Props {
disabled?: boolean;
response: string;
placement: string;
}
withDefaults(defineProps<Props>(), {
disabled: false
});
const pressedVote = ref(false);
Expand Down
18 changes: 6 additions & 12 deletions client/src/components/responseMatching/MatchCard.vue
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
<script setup lang="ts">
import ClickMp3 from '@/assets/audio/click2.mp3';
import { AudioWrap } from '@/mixins/audiowrap.js';
import { type PropType, computed, ref } from 'vue';
import { computed, ref } from 'vue';
import type { Player } from ':common/stateTypes.js';
import { type Match, useGameStore } from '@/stores/game.js';
import { useRoomStore } from '@/stores/room.js';
import { useI18n } from 'vue-i18n';
const props = defineProps({
player: {
type: Object as PropType<Player>,
required: true
},
match: {
type: Object as PropType<Match>,
required: true
}
});
const props = defineProps<{
player: Player;
match: Match;
}>();
const click = new AudioWrap(ClickMp3);
Expand All @@ -24,7 +18,7 @@ const hovering = ref(false);
const gameStore = useGameStore();
const roomStore = useRoomStore();
const showUnmatch = computed((): boolean => {
const showUnmatch = computed<boolean>(() => {
return props.player?.name === roomStore.name && !props.match?.exact;
});
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/responseMatching/MatchingSummary.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const click = new AudioWrap(ClickMp3);
const gameStore = useGameStore();
const roomStore = useRoomStore();
const matchers = computed((): Player[] => {
const matchers = computed<Player[]>(() => {
return roomStore.players.filter((player: Player) => player.active && player.id !== gameStore.selector!.id);
});
Expand Down
Loading

0 comments on commit d9e7889

Please sign in to comment.