diff --git a/client/package-lock.json b/client/package-lock.json index 456aba1c..6bb6e06c 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -11,6 +11,7 @@ "@kangc/v-md-editor": "^2.3.17", "axios": "^1.5.1", "babel-plugin-prismjs": "^2.1.0", + "ef-infinite-canvas": "^0.6.6", "form-data": "^4.0.0", "jquery": "^3.7.1", "jquery-ui": "^1.13.3", @@ -5263,6 +5264,12 @@ "dev": true, "license": "MIT" }, + "node_modules/ef-infinite-canvas": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/ef-infinite-canvas/-/ef-infinite-canvas-0.6.6.tgz", + "integrity": "sha512-EB9hawOUrFJ0eJz3MSxRnLcTodoji99zZVQSdvCTHVq1/6LQF/BVI/L3K8+1VgPW/aTSOTJiOGzqrm+PpMx0EA==", + "license": "MIT" + }, "node_modules/electron-to-chromium": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.2.tgz", diff --git a/client/package.json b/client/package.json index c72d6de9..cae4980c 100644 --- a/client/package.json +++ b/client/package.json @@ -12,6 +12,7 @@ "@kangc/v-md-editor": "^2.3.17", "axios": "^1.5.1", "babel-plugin-prismjs": "^2.1.0", + "ef-infinite-canvas": "^0.6.6", "form-data": "^4.0.0", "jquery": "^3.7.1", "jquery-ui": "^1.13.3", diff --git a/client/src/assets/base.css b/client/src/assets/base.css index be060bf0..3a4c1127 100644 --- a/client/src/assets/base.css +++ b/client/src/assets/base.css @@ -59,6 +59,8 @@ --color-background-softest: var(--c-white-softest); --color-button-active: var(--c-white-muter); + --text-disabled: #7e7e7e; + --color-scrollbar: var(--c-white-muter); --color-hover: var(--c-white-mute); @@ -92,6 +94,7 @@ --separator: var(--c-white-mute); --chat-background: var(--c-blacker); + --text-disabled: #7e7e7e; --color-hover: var() } diff --git a/client/src/assets/main.css b/client/src/assets/main.css index 67762030..0c819d44 100644 --- a/client/src/assets/main.css +++ b/client/src/assets/main.css @@ -60,6 +60,13 @@ a { flex-grow: 1; } +.btn-green { + background-color: var(--c-button-green); +} +.btn-green:hover { + background-color: var(--c-button-green-hover); +} + hr { border: 0; height: 1px; diff --git a/client/src/main.js b/client/src/main.js index 862dd74c..3bd4ad72 100644 --- a/client/src/main.js +++ b/client/src/main.js @@ -35,6 +35,7 @@ VueMarkdownEditor.use(createKatexPlugin()); const app = createApp(App).use(VueMarkdownEditor); +app.config.globalProperties.emitter = emitter app.config.globalProperties.rollWindows = { login: reactive([]), register: reactive([]), diff --git a/client/src/services/Dragonroll.js b/client/src/services/Dragonroll.js index 2df98a0b..b4118e1c 100644 --- a/client/src/services/Dragonroll.js +++ b/client/src/services/Dragonroll.js @@ -5,17 +5,31 @@ import Api from '@/services/Api' import { backendUrl } from './BackendURL'; import { GetUser } from './User'; +let emitter; + +function SetEmitter(newEmitter){ + emitter = newEmitter +} + +function DisplayToast(color, text, duration = 1000){ + emitter.emit("toast", {color, text, duration}); +} + export const socket = io(backendUrl) let currentCampaign = null; +let currentPlayer = null; const players = ref([]); let GetPlayerList = () => { return players; }; +let GetCampaign = () => { return currentCampaign; }; +let GetClient = () => { return currentPlayer; }; socket.on('update-players', data => { players.value = []; Object.keys(data).forEach((key) => { players.value.push(data[key]); + if(GetUser()._id == data[key].user._id) currentPlayer = data[key]; }); }) @@ -34,10 +48,22 @@ function Disconnect(){ currentCampaign = null; } +function GetPlayer(player_campaign){ + let index = players.value.findIndex((p) => {return p._id == player_campaign}); + if(index != -1) return players.value[index]; +} + export { + SetEmitter, + + DisplayToast, + DisplayCampaign, ConnectToCampaign, Disconnect, + GetCampaign, + GetClient, GetPlayerList, + GetPlayer, }; \ No newline at end of file diff --git a/client/src/services/Game.js b/client/src/services/Game.js new file mode 100644 index 00000000..8372ba7f --- /dev/null +++ b/client/src/services/Game.js @@ -0,0 +1,20 @@ +import { ref } from "vue"; + +const inGameRef = ref(false); +let InGameRef = () => inGameRef; + +function LaunchGame(){ + inGameRef.value = true; + console.log("jdksadjlo") +} + +function ExitGame(){ + inGameRef.value = false; +} + +export { + LaunchGame, + ExitGame, + + InGameRef +}; \ No newline at end of file diff --git a/client/src/views/HomeView.vue b/client/src/views/HomeView.vue index 99e710de..f1ab5a3d 100644 --- a/client/src/views/HomeView.vue +++ b/client/src/views/HomeView.vue @@ -2,14 +2,22 @@ import { onMounted } from 'vue'; import { RouterLink, RouterView } from 'vue-router' +import useEmitter from '@/services/Emitter'; +const emitter = useEmitter(); + import WindowManager from '@/views/managers/WindowManager.vue' import { GetUser } from '@/services/User' import { CreateWindow } from '@/services/Windows' +import Toast from './partials/Toast.vue'; +import { DisplayToast, SetEmitter } from '../services/Dragonroll'; +import GameManager from './managers/GameManager.vue'; onMounted(() => { + SetEmitter(emitter); if(GetUser()){ CreateWindow('main_menu') + DisplayToast('green', 'Logged in successfully as ' + GetUser().username + '!', 3000) return; } CreateWindow('login'); @@ -20,6 +28,8 @@ onMounted(() => { diff --git a/client/src/views/managers/GameManager.vue b/client/src/views/managers/GameManager.vue new file mode 100644 index 00000000..bc9d1a49 --- /dev/null +++ b/client/src/views/managers/GameManager.vue @@ -0,0 +1,39 @@ + + + + + + + \ No newline at end of file diff --git a/client/src/views/partials/PlayerEntry.vue b/client/src/views/partials/PlayerEntry.vue index a94e92fb..58edefcf 100644 --- a/client/src/views/partials/PlayerEntry.vue +++ b/client/src/views/partials/PlayerEntry.vue @@ -2,38 +2,60 @@ import { onMounted, onUpdated, ref } from 'vue'; import Api from '@/services/Api.js' import { backendUrl } from '../../services/BackendURL'; +import { GetClient, GetPlayer, GetPlayerList } from '../../services/Dragonroll'; +import { GetUser } from '../../services/User'; const props = defineProps(['player']); -const player = props.player; +let player = props.player; const playerName = ref(""); const isDm = ref(false); const avatar = ref(null); +const container = ref(null); +const status = ref(""); function retrieveAvatar(){ let userAvatarDisplay = avatar.value; - Api().get('/user/retrieve-avatar?username=' + player.data.username).then((response) => { + Api().get('/user/retrieve-avatar?username=' + player.user.username).then((response) => { if(response.data.image) userAvatarDisplay.src = backendUrl + "public/" + response.data.image; }).catch((err) => console.log("Internal error")); } onMounted(() => { - playerName.value = player.data.username; + playerName.value = player.user.username; if(player.is_dm) isDm.value = true; - + if(player.online) status.value = "online"; + else status.value = ""; + retrieveAvatar(); + + if(player.user._id == GetUser()._id){ + container.value.classList.add("current-player"); + } +}); + + +onUpdated(() => { + player = GetPlayer(player._id); + playerName.value = player.user.username; + if(player.is_dm) isDm.value = true; + if(player.online) status.value = "online"; + else status.value = ""; });