More code

This commit is contained in:
Lordmau5 2023-11-14 14:09:46 +01:00
parent bfbf625f87
commit b61bc8d991
18 changed files with 10773 additions and 173 deletions

View File

@ -67,6 +67,21 @@
"watch": true,
"watchEffect": true,
"watchPostEffect": true,
"watchSyncEffect": true
"watchSyncEffect": true,
"NavbarComponent": true,
"SidebarComponent": true,
"Emit": true,
"Hook": true,
"Inject": true,
"Model": true,
"Prop": true,
"Provide": true,
"Setup": true,
"VModel": true,
"Vanilla": true,
"Watch": true,
"toNative": true,
"Vue": true,
"ComponentBase": true
}
}

18
auto-imports.d.ts vendored
View File

@ -5,5 +5,21 @@
// Generated by unplugin-auto-import
export {}
declare global {
const Component: typeof import('vue-facing-decorator')['Component']
const ComponentBase: typeof import('vue-facing-decorator')['ComponentBase']
const Emit: typeof import('vue-facing-decorator')['Emit']
const Hook: typeof import('vue-facing-decorator')['Hook']
const Inject: typeof import('vue-facing-decorator')['Inject']
const Model: typeof import('vue-facing-decorator')['Model']
const NavbarComponent: typeof import('./src/components/NavbarComponent.vue')['default']
const Prop: typeof import('vue-facing-decorator')['Prop']
const Provide: typeof import('vue-facing-decorator')['Provide']
const Ref: typeof import('vue-facing-decorator')['Ref']
const Setup: typeof import('vue-facing-decorator')['Setup']
const SidebarComponent: typeof import('./src/components/SidebarComponent.vue')['default']
const VModel: typeof import('vue-facing-decorator')['VModel']
const Vanilla: typeof import('vue-facing-decorator')['Vanilla']
const Vue: typeof import('vue-facing-decorator')['Vue']
const Watch: typeof import('vue-facing-decorator')['Watch']
const toNative: typeof import('vue-facing-decorator')['toNative']
}

9
components.d.ts vendored
View File

@ -7,17 +7,10 @@ export {}
declare module 'vue' {
export interface GlobalComponents {
Avatar: typeof import('primevue/avatar')['default']
Badge: typeof import('primevue/badge')['default']
Button: typeof import('primevue/button')['default']
InputText: typeof import('primevue/inputtext')['default']
Menubar: typeof import('primevue/menubar')['default']
EditorComponent: typeof import('./src/components/EditorComponent.vue')['default']
NavbarComponent: typeof import('./src/components/NavbarComponent.vue')['default']
PButton: typeof import('primevue/button')['default']
PSidebar: typeof import('primevue/sidebar')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
Sidebar: typeof import('primevue/sidebar')['default']
SidebarComponent: typeof import('./src/components/SidebarComponent.vue')['default']
}
}

View File

@ -18,6 +18,7 @@
"quasar": "^2.13.1",
"reflect-metadata": "^0.1.13",
"vue": "^3.3.4",
"vue-facing-decorator": "^3.0.4",
"vue-router": "^4.2.5"
},
"devDependencies": {

11
pnpm-lock.yaml generated
View File

@ -23,6 +23,9 @@ dependencies:
vue:
specifier: ^3.3.4
version: 3.3.8(typescript@5.2.2)
vue-facing-decorator:
specifier: ^3.0.4
version: 3.0.4(vue@3.3.8)
vue-router:
specifier: ^4.2.5
version: 4.2.5(vue@3.3.8)
@ -3273,6 +3276,14 @@ packages:
- supports-color
dev: true
/vue-facing-decorator@3.0.4(vue@3.3.8):
resolution: {integrity: sha512-Lk90PevJllB6qRRdLvLFjATZrv00nof1Ob6afavKL7Pc7V3eEin3vhdvEDRORdWKVvNoXhJbHejngWVuT0Pt0g==}
peerDependencies:
vue: ^3.0.0
dependencies:
vue: 3.3.8(typescript@5.2.2)
dev: false
/vue-router@4.2.5(vue@3.3.8):
resolution: {integrity: sha512-DIUpKcyg4+PTQKfFPX88UWhlagBEBEfJ5A8XDXRJLUnZOvcpMF8o/dnL90vpVkGaPbjvXazV/rC1qBKrZlFugw==}
peerDependencies:

View File

@ -10,37 +10,18 @@
</q-layout>
</template>
<script setup lang="ts">
<script lang="ts">
import {
ref
} from 'vue';
import {
RouterView
} from 'vue-router';
Component, Vue, toNative
} from 'vue-facing-decorator';
const leftDrawerOpen = ref(false);
@Component
class MainPage extends Vue {
leftDrawerOpen = false;
const toggleLeftDrawer = () => {
leftDrawerOpen.value = !leftDrawerOpen.value;
};
function test(): string {
const asdf = {
hello: 4,
hallo: 5,
'test-4': 'hallo'
};
if (asdf.hello === 4) {
asdf.hello = 5;
toggleLeftDrawer() {
this.leftDrawerOpen = !this.leftDrawerOpen;
}
else {
asdf.hallo = 4;
}
console.log(asdf);
return asdf['test-4'];
}
test();
export default toNative(MainPage);
</script>

View File

@ -0,0 +1,3 @@
<template>
<span>Editor</span>
</template>

View File

@ -13,10 +13,13 @@
</q-header>
</template>
<script setup lang="ts">
const emit = defineEmits([ 'toggleLeftDrawer' ]);
const toggleLeftDrawer = function() {
emit('toggleLeftDrawer');
};
<script lang="ts">
@Component({
emits: [ 'toggleLeftDrawer' ]
})
class NavbarComponent extends Vue {
@Emit
toggleLeftDrawer() {}
}
export default toNative(NavbarComponent);
</script>

View File

@ -1,12 +1,9 @@
<template>
<q-drawer :model-value="props.drawer" side="left" elevated>
<q-drawer :model-value="drawer" side="left" elevated>
<q-scroll-area class="fit">
<q-list>
<template v-for="(menuItem, index) in menuList" :key="index">
<!-- <router-link :to="{ name: 'home' }"> -->
<q-space v-if="menuItem.type === 'spacer'"/>
<template v-else>
<q-item clickable v-ripple :to="{ name: menuItem.to }">
<q-item-section avatar>
<q-icon :name="menuItem.icon" />
@ -15,20 +12,24 @@
{{ menuItem.label }}
</q-item-section>
</q-item>
<!-- </router-link> -->
<q-separator :key="'sep' + index" v-if="menuItem.separator" />
</template>
</template>
</q-list>
</q-scroll-area>
</q-drawer>
</template>
<script setup lang="ts">
const props = defineProps([ 'drawer' ]);
<script lang="ts">
@Component
class SidebarComponent extends Vue {
@Prop({
default: false,
required: true
})
drawer!: boolean;
const menuList = [
menuList = [
{
icon: 'home',
label: 'Home',
@ -36,39 +37,41 @@ const menuList = [
to: 'home'
},
{
icon: 'send',
label: 'Outbox',
icon: 'edit',
label: 'Editor',
separator: false,
to: 'send'
},
{
icon: 'delete',
label: 'Trash',
separator: false
},
{
icon: 'error',
label: 'Spam',
separator: true
},
{
type: 'spacer'
},
{
icon: 'settings',
label: 'Settings',
separator: false
},
{
icon: 'feedback',
label: 'Send Feedback',
separator: false
},
{
icon: 'help',
iconColor: 'primary',
label: 'Help',
separator: false
to: 'editor'
}
// {
// icon: 'delete',
// label: 'Trash',
// separator: false
// },
// {
// icon: 'error',
// label: 'Spam',
// separator: true
// },
// {
// type: 'spacer'
// },
// {
// icon: 'settings',
// label: 'Settings',
// separator: false
// },
// {
// icon: 'feedback',
// label: 'Send Feedback',
// separator: false
// },
// {
// icon: 'help',
// iconColor: 'primary',
// label: 'Help',
// separator: false
// }
];
}
export default toNative(SidebarComponent);
</script>

View File

@ -1,7 +1,6 @@
import {
Transform,
Type,
instanceToPlain, plainToInstance
plainToInstance
} from 'class-transformer';
function stringCompare(a: string, b: string) {
@ -10,28 +9,7 @@ function stringCompare(a: string, b: string) {
}) === 0;
}
interface IBingoGame {
id: string;
name: string;
description: string;
generator: 'simple' | 'srl_v5' | 'srl_v8';
goals: IBingoGoal[];
groups: IBingoGroup[];
}
interface IBingoGoal {
name: string;
group?: IBingoGroup;
tags: string[];
possible_spaces: number[];
}
interface IBingoGroup {
name: string;
parent?: IBingoGroup;
}
class BingoGame implements IBingoGame {
export class BingoGame {
id: string;
name: string;
@ -41,10 +19,10 @@ class BingoGame implements IBingoGame {
generator: 'simple' | 'srl_v5' | 'srl_v8' = 'simple';
@Type(() => BingoGoal)
goals: IBingoGoal[] = [];
goals: BingoGoal[] = [];
@Type(() => BingoGroup)
groups: IBingoGroup[] = [];
groups: BingoGroup[] = [];
constructor(id: string, name: string, description: string) {
this.id = id;
@ -52,47 +30,74 @@ class BingoGame implements IBingoGame {
this.description = description;
}
addGoal(goal: IBingoGoal): void {
addGoal(goal: BingoGoal): void {
if (this.goals.some(_goal => stringCompare(_goal.name, goal.name)))
return;
this.goals.push(goal);
}
removeGoal(goal: IBingoGoal): void {
removeGoal(goal: BingoGoal): void {
this.goals = this.goals.filter(_goal => !stringCompare(_goal.name, goal.name));
}
addGroup(group: IBingoGroup): void {
removeGoalByName(name: string): void {
const goal = this.goals.find(goal => stringCompare(goal.name, name));
if (goal)
this.removeGoal(goal);
}
addGroup(group: BingoGroup): void {
if (this.groups.some(_group => stringCompare(_group.name, group.name)))
return;
this.groups.push(group);
}
removeGroup(group: IBingoGroup): boolean {
removeGroup(group: BingoGroup): boolean {
// Group has parent, don't delete
if (this.groups.some(_group => _group.parent && stringCompare(_group.parent.name, group.name)))
return false;
const isParent = this.groups.find(_group => _group.parent && stringCompare(_group.parent.name, group.name));
if (isParent) {
console.error('This group is still a parent of:', isParent.name);
if (this.goals.some(goal => goal.group && stringCompare(goal.group.name, group.name)))
return false;
// TODO: Make sure no goal is still using group;
// boolean override "force_remove" which will remove the group from all goals
console.log('deltee', group);
}
// One or more goals still use this group, don't delete
const isGoal = this.goals.find(goal => goal.group && stringCompare(goal.group.name, group.name));
if (isGoal) {
console.error('This group is still used by:', isGoal.name);
return false;
}
this.groups = this.groups.filter(_group => !stringCompare(_group.name, group.name));
console.log(this.groups);
return true;
}
removeGroupByName(name: string): boolean {
const group = this.groups.find(group => stringCompare(group.name, name));
return group ? this.removeGroup(group) : false;
}
class BingoGoal implements IBingoGoal {
getGoalsByTags(...tags: string[]): BingoGoal[] {
return this.goals.filter(goal => goal.tags.some(_tag => tags.some(tag => stringCompare(_tag, tag))));
}
}
function getRandomInt(max: number): number {
return Math.floor(Math.random() * max);
}
export class BingoGoal {
// id: string; // uuid-by-string maybe? https://www.npmjs.com/package/uuid-by-string
name: string;
group?: IBingoGroup;
group?: BingoGroup;
tags: string[] = [];
@ -101,9 +106,16 @@ class BingoGoal implements IBingoGoal {
constructor(name: string, group?: BingoGroup) {
this.name = name;
this.group = group;
for (let i = 0; i < 25; i++) {
if (getRandomInt(2) == 0)
continue;
this.possible_spaces.push(i);
}
}
addTag(tag: string): IBingoGoal {
addTag(tag: string): BingoGoal {
if (this.tags.includes(tag))
return this;
@ -112,8 +124,10 @@ class BingoGoal implements IBingoGoal {
return this;
}
removeTag(tag: string): void {
removeTag(tag: string): BingoGoal {
this.tags = this.tags.filter(_tag => !stringCompare(_tag, tag));
return this;
}
setGroup(group: BingoGroup) {
@ -125,11 +139,11 @@ class BingoGoal implements IBingoGoal {
}
}
class BingoGroup implements IBingoGroup {
export class BingoGroup {
name: string;
@Type(() => BingoGroup)
parent?: IBingoGroup;
parent?: BingoGroup;
constructor(name: string, parent?: BingoGroup) {
this.name = name;
@ -137,6 +151,8 @@ class BingoGroup implements IBingoGroup {
}
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function test(): void {
const game = new BingoGame('yakuza_0', 'Yakuza 0', 'The funny game we used for all bingos.');
const battle_group = new BingoGroup('Battle');
const defeat_enemies = new BingoGroup('Defeat enemies on the street', battle_group);
@ -151,14 +167,17 @@ game.addGoal(easy);
game.addGoal(normal);
game.addGoal(hard);
const jsonifiedInstance = instanceToPlain(game);
// const jsonifiedInstance = instanceToPlain(game);
// console.log(JSON.stringify(jsonifiedInstance));
// console.log(JSON.stringify(game));
const json_string = '{"id":"yakuza_0","name":"Yakuza 0","description":"The funny game we used for all bingos.","generator":"simple","goals":[{"name":"Defeat 50 enemies on the street","tags":["Easy"],"group":{"name":"Defeat enemies on the street","parent":{"name":"Battle"}},"possible_spaces":[]},{"name":"Defeat 150 enemies on the street","tags":["Normal"],"group":{"name":"Defeat enemies on the street","parent":{"name":"Battle"}},"possible_spaces":[]},{"name":"Defeat 300 enemies on the street","tags":["Hard"],"group":{"name":"Defeat enemies on the street","parent":{"name":"Battle"}},"possible_spaces":[]}],"groups":[{"name":"Battle"},{"name":"Defeat enemies on the street","parent":{"name":"Battle"}}]}';
const parsed: JSON = JSON.parse(json_string);
const parsed_game = plainToInstance(BingoGame, parsed);
console.log(parsed_game);
// console.log(JSON.stringify(other_game) === JSON.stringify(jsonifiedInstance));
parsed_game.removeGroup(defeat_enemies);
console.log(parsed_game.goals);
// parsed_game.removeGroup(defeat_enemies);
// console.log(parsed_game.goals);
}

41
src/js/ParseGamesJSON.ts Normal file
View File

@ -0,0 +1,41 @@
// Example code to convert the old format to the new one
import {
BingoGame, BingoGoal, BingoGroup
} from '@/js/Bingo.js';
import json from './games.json';
import {
instanceToPlain
} from 'class-transformer';
function run() {
const games: Map<string, BingoGame> = new Map;
for (const j_game of json) {
const game = new BingoGame(j_game.game_name, j_game.game_name, 'Empty Description');
for (const j_cat of j_game.categories) {
const category = new BingoGroup(j_cat.category_name);
game.addGroup(category);
for (const j_group of j_cat.groups) {
const group = new BingoGroup(j_group.group_name, category);
game.addGroup(group);
for (const j_goal of j_group.options) {
const goal = new BingoGoal(j_goal.title, group);
goal.addTag(j_goal.difficulty);
game.addGoal(goal);
}
}
}
games.set(game.name, game);
}
console.log(instanceToPlain(games));
console.log(JSON.stringify(instanceToPlain(games)));
}
run();

1
src/js/games.json Normal file

File diff suppressed because one or more lines are too long

10488
src/js/singlegame.json Normal file

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,7 @@ import {
} from 'vue-router';
// import HomeView from '../views/HomeView.vue'
import MainPage from '@/views/MainPage.vue';
import EditorPage from '@/views/EditorPage.vue';
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
@ -13,9 +14,9 @@ const router = createRouter({
component: MainPage
},
{
path: '/send',
name: 'send',
component: MainPage
path: '/editor',
name: 'editor',
component: EditorPage
}
// {
// path: '/about',

3
src/views/EditorPage.vue Normal file
View File

@ -0,0 +1,3 @@
<template>
<EditorComponent/>
</template>

View File

@ -2,6 +2,6 @@
<span>Hello world</span>
</template>
<script lang="ts">
import '@/js/Bingo.js';
<script setup lang="ts">
import '@/js/ParseGamesJSON.ts';
</script>

View File

@ -5,7 +5,8 @@
"auto-imports.d.ts",
"components.d.ts",
"src/**/*",
"src/**/*.vue"
"src/**/*.vue",
"src/**/*.json"
],
"exclude": [
"src/**/__tests__/*"

View File

@ -39,6 +39,26 @@ export default defineConfig({
// 'vue',
// 'vue-router'
// ],
imports: [ {
'vue-facing-decorator': [
'Component',
'ComponentBase',
'Setup',
'Ref',
'Watch',
'Prop',
'Provide',
'Inject',
'Emit',
'VModel',
'Model',
'Vanilla',
'Hook',
'toNative',
'Vue'
]
} ],
dirs: [ './src/components/**' ],
dts: true,
eslintrc: {