mirror of
https://github.com/overte-org/overte.git
synced 2025-06-15 17:59:16 +02:00
Metaverse connection is working.
This commit is contained in:
parent
da464b2f40
commit
4ae378e90a
14 changed files with 358 additions and 151 deletions
|
@ -1,109 +1,112 @@
|
||||||
const { resolve } = require('path');
|
const { resolve } = require('path');
|
||||||
module.exports = {
|
module.exports = {
|
||||||
// https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy
|
// https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy
|
||||||
// This option interrupts the configuration hierarchy at this file
|
// This option interrupts the configuration hierarchy at this file
|
||||||
// Remove this if you have an higher level ESLint config file (it usually happens into a monorepos)
|
// Remove this if you have an higher level ESLint config file (it usually happens into a monorepos)
|
||||||
root: true,
|
root: true,
|
||||||
|
|
||||||
// https://eslint.vuejs.org/user-guide/#how-to-use-custom-parser
|
// https://eslint.vuejs.org/user-guide/#how-to-use-custom-parser
|
||||||
// Must use parserOptions instead of "parser" to allow vue-eslint-parser to keep working
|
// Must use parserOptions instead of "parser" to allow vue-eslint-parser to keep working
|
||||||
// `parser: 'vue-eslint-parser'` is already included with any 'plugin:vue/**' config and should be omitted
|
// `parser: 'vue-eslint-parser'` is already included with any 'plugin:vue/**' config and should be omitted
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
// https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/parser#configuration
|
// https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/parser#configuration
|
||||||
// https://github.com/TypeStrong/fork-ts-checker-webpack-plugin#eslint
|
// https://github.com/TypeStrong/fork-ts-checker-webpack-plugin#eslint
|
||||||
// Needed to make the parser take into account 'vue' files
|
// Needed to make the parser take into account 'vue' files
|
||||||
extraFileExtensions: ['.vue'],
|
extraFileExtensions: ['.vue'],
|
||||||
parser: '@typescript-eslint/parser',
|
parser: '@typescript-eslint/parser',
|
||||||
project: resolve(__dirname, './tsconfig.json'),
|
project: resolve(__dirname, './tsconfig.json'),
|
||||||
tsconfigRootDir: __dirname,
|
tsconfigRootDir: __dirname,
|
||||||
ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features
|
ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features
|
||||||
sourceType: 'module' // Allows for the use of imports
|
sourceType: 'module' // Allows for the use of imports
|
||||||
},
|
},
|
||||||
|
|
||||||
env: {
|
env: {
|
||||||
browser: true
|
browser: true
|
||||||
},
|
},
|
||||||
|
|
||||||
// Rules order is important, please avoid shuffling them
|
// Rules order is important, please avoid shuffling them
|
||||||
extends: [
|
extends: [
|
||||||
// Base ESLint recommended rules
|
// Base ESLint recommended rules
|
||||||
// 'eslint:recommended',
|
// 'eslint:recommended',
|
||||||
|
|
||||||
// https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin#usage
|
// https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin#usage
|
||||||
// ESLint typescript rules
|
// ESLint typescript rules
|
||||||
'plugin:@typescript-eslint/recommended',
|
'plugin:@typescript-eslint/recommended',
|
||||||
// consider disabling this class of rules if linting takes too long
|
// consider disabling this class of rules if linting takes too long
|
||||||
'plugin:@typescript-eslint/recommended-requiring-type-checking',
|
'plugin:@typescript-eslint/recommended-requiring-type-checking',
|
||||||
|
|
||||||
// Uncomment any of the lines below to choose desired strictness,
|
// Uncomment any of the lines below to choose desired strictness,
|
||||||
// but leave only one uncommented!
|
// but leave only one uncommented!
|
||||||
// See https://eslint.vuejs.org/rules/#available-rules
|
// See https://eslint.vuejs.org/rules/#available-rules
|
||||||
'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention)
|
'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention)
|
||||||
// 'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability)
|
// 'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability)
|
||||||
// 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)
|
// 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)
|
||||||
|
|
||||||
'standard'
|
'standard'
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
plugins: [
|
plugins: [
|
||||||
// required to apply rules which need type information
|
// required to apply rules which need type information
|
||||||
'@typescript-eslint',
|
'@typescript-eslint',
|
||||||
|
|
||||||
// https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-file
|
// https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-file
|
||||||
// required to lint *.vue files
|
// required to lint *.vue files
|
||||||
'vue',
|
'vue',
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
globals: {
|
globals: {
|
||||||
ga: 'readonly', // Google Analytics
|
ga: 'readonly', // Google Analytics
|
||||||
cordova: 'readonly',
|
cordova: 'readonly',
|
||||||
__statics: 'readonly',
|
__statics: 'readonly',
|
||||||
__QUASAR_SSR__: 'readonly',
|
__QUASAR_SSR__: 'readonly',
|
||||||
__QUASAR_SSR_SERVER__: 'readonly',
|
__QUASAR_SSR_SERVER__: 'readonly',
|
||||||
__QUASAR_SSR_CLIENT__: 'readonly',
|
__QUASAR_SSR_CLIENT__: 'readonly',
|
||||||
__QUASAR_SSR_PWA__: 'readonly',
|
__QUASAR_SSR_PWA__: 'readonly',
|
||||||
process: 'readonly',
|
process: 'readonly',
|
||||||
Capacitor: 'readonly',
|
Capacitor: 'readonly',
|
||||||
chrome: 'readonly'
|
chrome: 'readonly'
|
||||||
},
|
},
|
||||||
|
|
||||||
// add your custom rules here
|
// add your custom rules here
|
||||||
rules: {
|
rules: {
|
||||||
// allow async-await
|
// allow async-await
|
||||||
'generator-star-spacing': 'off',
|
'generator-star-spacing': 'off',
|
||||||
// allow paren-less arrow functions
|
// allow paren-less arrow functions
|
||||||
'arrow-parens': 'off',
|
'arrow-parens': 'off',
|
||||||
'one-var': 'off',
|
'one-var': 'off',
|
||||||
'no-void': 'off',
|
'no-void': 'off',
|
||||||
'multiline-ternary': 'off',
|
'multiline-ternary': 'off',
|
||||||
|
'quote-props': 'off',
|
||||||
|
|
||||||
'import/first': 'off',
|
'import/first': 'off',
|
||||||
'import/namespace': 'error',
|
'import/namespace': 'error',
|
||||||
'import/default': 'error',
|
'import/default': 'error',
|
||||||
'import/export': 'error',
|
'import/export': 'error',
|
||||||
'import/extensions': 'off',
|
'import/extensions': 'off',
|
||||||
'import/no-unresolved': 'off',
|
'import/no-unresolved': 'off',
|
||||||
'import/no-extraneous-dependencies': 'off',
|
'import/no-extraneous-dependencies': 'off',
|
||||||
'prefer-promise-reject-errors': 'off',
|
'prefer-promise-reject-errors': 'off',
|
||||||
'indent': ["error", 4],
|
'indent': ["error", 4],
|
||||||
'semi': ["error", "always"],
|
'semi': ["error", "always"],
|
||||||
|
|
||||||
// TypeScript
|
// TypeScript
|
||||||
quotes: ['warn', 'double', { avoidEscape: true }],
|
quotes: ['warn', 'double', { avoidEscape: true }],
|
||||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||||
|
|
||||||
// TypeScript -> Remove these when we start using TypeScript in the project.
|
// TypeScript -> Remove these when we start using TypeScript in the project.
|
||||||
'@typescript-eslint/no-unsafe-assignment': 'off',
|
'@typescript-eslint/no-unsafe-assignment': 'off',
|
||||||
'@typescript-eslint/no-unsafe-call': 'off',
|
'@typescript-eslint/no-unsafe-call': 'off',
|
||||||
'@typescript-eslint/unbound-method': 'off',
|
'@typescript-eslint/unbound-method': 'off',
|
||||||
'@typescript-eslint/no-unsafe-member-access': 'off',
|
'@typescript-eslint/no-unsafe-member-access': 'off',
|
||||||
'@typescript-eslint/no-floating-promises': 'off',
|
'@typescript-eslint/no-floating-promises': 'off',
|
||||||
'@typescript-eslint/restrict-template-expressions': 'off',
|
'@typescript-eslint/restrict-template-expressions': 'off',
|
||||||
|
'@typescript-eslint/no-var-requires': 'off',
|
||||||
|
'@typescript-eslint/no-unsafe-return': 'off',
|
||||||
|
|
||||||
// allow debugger during development only
|
// allow debugger during development only
|
||||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
|
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,13 @@
|
||||||
|
<!--
|
||||||
|
// App.vue
|
||||||
|
//
|
||||||
|
// Created by Kalila L. on Sep. 4th, 2021.
|
||||||
|
// Copyright 2021 Vircadia contributors.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<router-view />
|
<router-view />
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { boot } from "quasar/wrappers";
|
import { boot } from "quasar/wrappers";
|
||||||
import axios, { AxiosInstance } from "axios";
|
import axios, { AxiosInstance } from "axios";
|
||||||
|
import Log from "../modules/utilities/log";
|
||||||
|
|
||||||
declare module "@vue/runtime-core" {
|
declare module "@vue/runtime-core" {
|
||||||
interface ComponentCustomProperties {
|
interface ComponentCustomProperties {
|
||||||
|
@ -7,6 +8,12 @@ declare module "@vue/runtime-core" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.info(Log.types.OTHER, "Bootstrapping Axios.");
|
||||||
|
|
||||||
|
axios.defaults.headers.common = {
|
||||||
|
"x-vircadia-error-handle": "badrequest"
|
||||||
|
};
|
||||||
|
|
||||||
// Be careful when using SSR for cross-request state pollution
|
// Be careful when using SSR for cross-request state pollution
|
||||||
// due to creating a Singleton instance here;
|
// due to creating a Singleton instance here;
|
||||||
// If any client changes this (global) instance, it might be a
|
// If any client changes this (global) instance, it might be a
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
// FIXME: Needs to be done correctly. Also universally? Maybe window.axios?
|
||||||
const axios = require("axios");
|
const axios = require("axios");
|
||||||
|
|
||||||
import Log from "../../../modules/utilities/log";
|
import Log from "../../../modules/utilities/log";
|
||||||
|
@ -64,43 +65,27 @@ export default {
|
||||||
username: "",
|
username: "",
|
||||||
password: "",
|
password: "",
|
||||||
showPassword: false,
|
showPassword: false,
|
||||||
|
// TODO: Needs to be stored somewhere central.
|
||||||
DEFAULT_METAVERSE_URL: "https://metaverse.vircadia.com/live"
|
DEFAULT_METAVERSE_URL: "https://metaverse.vircadia.com/live"
|
||||||
}),
|
}),
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
async onSubmit () {
|
async onSubmit () {
|
||||||
try {
|
const metaverseURL = await this.retrieveMetaverseUrl();
|
||||||
const metaverseURL = await this.retrieveMetaverseUrl();
|
const result = await this.attemptLogin(metaverseURL, this.username, this.password);
|
||||||
const result = await this.attemptLogin(metaverseURL, this.username, this.password);
|
|
||||||
|
|
||||||
this.$q.notify({
|
this.$emit("loginResult", { "success": result.success, "metaverse": metaverseURL, "data": result.response });
|
||||||
type: "positive",
|
|
||||||
textColor: "white",
|
|
||||||
icon: "cloud_done",
|
|
||||||
message: `Welcome ${this.username}.`
|
|
||||||
});
|
|
||||||
|
|
||||||
this.$emit("loginResult", true, result);
|
|
||||||
} catch (result) {
|
|
||||||
this.$q.notify({
|
|
||||||
type: "negative",
|
|
||||||
textColor: "white",
|
|
||||||
icon: "warning",
|
|
||||||
message: `Login attempted failed: ${result.error}`
|
|
||||||
});
|
|
||||||
|
|
||||||
this.$emit("loginResult", false, result);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// TODO: This needs to be addressed in a more modular fashion to reuse and save state across multiple components.
|
||||||
async retrieveMetaverseUrl () {
|
async retrieveMetaverseUrl () {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve) => {
|
||||||
axios.get("/api/metaverse_info")
|
axios.get("/api/metaverse_info")
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
Log.info(Log.types.METAVERSE, `Retrieved Metaverse URL ${response.metaverse_url}.`);
|
Log.info(Log.types.METAVERSE, `Retrieved Metaverse URL ${response.data.metaverse_url}.`);
|
||||||
resolve(response.metaverse_url);
|
resolve(response.data.metaverse_url);
|
||||||
}, (error) => {
|
}, (error) => {
|
||||||
Log.error(Log.types.METAVERSE, `Failed to retrieve Metaverse URL, using default URL ${this.DEFAULT_METAVERSE_URL} instead.`);
|
Log.error(Log.types.METAVERSE, `Failed to retrieve Metaverse URL, using default URL ${this.DEFAULT_METAVERSE_URL} instead. Error: ${error}`);
|
||||||
resolve(this.DEFAULT_METAVERSE_URL);
|
resolve(this.DEFAULT_METAVERSE_URL);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -109,7 +94,7 @@ export default {
|
||||||
async attemptLogin (metaverse, username, password) {
|
async attemptLogin (metaverse, username, password) {
|
||||||
Log.info(Log.types.METAVERSE, `Attempting to login as ${username}.`);
|
Log.info(Log.types.METAVERSE, `Attempting to login as ${username}.`);
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve) => {
|
||||||
axios.post(`${metaverse}/oauth/token`, {
|
axios.post(`${metaverse}/oauth/token`, {
|
||||||
grant_type: "password",
|
grant_type: "password",
|
||||||
scope: "owner", // as opposed to 'domain', we're asking for a user token
|
scope: "owner", // as opposed to 'domain', we're asking for a user token
|
||||||
|
@ -118,13 +103,15 @@ export default {
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
Log.info(Log.types.METAVERSE, `Successfully got key and details for ${username}.`);
|
Log.info(Log.types.METAVERSE, `Successfully got key and details for ${username}.`);
|
||||||
resolve(response.data);
|
resolve({ "success": true, "response": response.data });
|
||||||
}, (error) => {
|
}, (error) => {
|
||||||
Log.error(Log.types.METAVERSE, `Failed to get key and details for ${username}.`);
|
Log.error(Log.types.METAVERSE, `Failed to get key and details for ${username}.`);
|
||||||
if (error.response && error.response.data) {
|
if (error.response && error.response.data) {
|
||||||
reject(error.response.data);
|
resolve({ "success": false, "response": error.response.data });
|
||||||
|
} else if (error) {
|
||||||
|
resolve({ "success": false, "response": error });
|
||||||
} else {
|
} else {
|
||||||
reject("Unknown reason.");
|
resolve({ "success": false, "response": "Unknown reason." });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -21,12 +21,18 @@
|
||||||
<q-separator />
|
<q-separator />
|
||||||
|
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<MetaverseLogin></MetaverseLogin>
|
<MetaverseLogin @loginResult="onLoginAttempt"></MetaverseLogin>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
// FIXME: Needs to be done correctly. Also universally? Maybe window.axios?
|
||||||
|
const axios = require("axios");
|
||||||
|
|
||||||
|
// Components
|
||||||
import MetaverseLogin from "../components/login/MetaverseLogin.vue";
|
import MetaverseLogin from "../components/login/MetaverseLogin.vue";
|
||||||
|
// Modules
|
||||||
|
import Log from "../../modules/utilities/log";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ConnectMetaverse",
|
name: "ConnectMetaverse",
|
||||||
|
@ -35,10 +41,90 @@ export default {
|
||||||
MetaverseLogin
|
MetaverseLogin
|
||||||
},
|
},
|
||||||
|
|
||||||
|
emits: ["connectionResult"],
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
}),
|
}),
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
onLoginAttempt (result) {
|
||||||
|
if (result.success === true) {
|
||||||
|
Log.info(Log.types.METAVERSE, `Successfully logged in as ${result.data.account_name} for Metaverse linking.`);
|
||||||
|
// Get a token for our server from the Metaverse.
|
||||||
|
axios.post(`${result.metaverse}/api/v1/token/new`, {}, {
|
||||||
|
params: {
|
||||||
|
// "asAdmin": store.account.useAsAdmin,
|
||||||
|
"scope": "domain"
|
||||||
|
},
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Bearer ${result.data.access_token}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(async (response) => {
|
||||||
|
Log.info(Log.types.METAVERSE, `Successfully got Domain token for Metaverse linking.`);
|
||||||
|
|
||||||
|
var settingsToCommit = {
|
||||||
|
"metaverse": {
|
||||||
|
"access_token": response.data.data.token
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var committed = await this.commitSettings(settingsToCommit);
|
||||||
|
|
||||||
|
if (committed === true) {
|
||||||
|
Log.info(Log.types.METAVERSE, `Successfully committed Domain server access token for the Metaverse.`);
|
||||||
|
this.$q.notify({
|
||||||
|
type: "positive",
|
||||||
|
textColor: "white",
|
||||||
|
icon: "cloud_done",
|
||||||
|
message: `Successfully linked your server to the Metaverse.`
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$emit("connectionResult", { "success": true });
|
||||||
|
} else {
|
||||||
|
Log.error(Log.types.METAVERSE, `Failed to link server with Metaverse: Could not commit token to settings.`);
|
||||||
|
this.$q.notify({
|
||||||
|
type: "negative",
|
||||||
|
textColor: "white",
|
||||||
|
icon: "warning",
|
||||||
|
message: `Metaverse link attempt failed because the settings were unable to be saved.`
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$emit("connectionResult", { "success": false });
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((result) => {
|
||||||
|
Log.error(Log.types.METAVERSE, `Failed to link server with Metaverse: ${result.responseJSON.error}`);
|
||||||
|
this.$q.notify({
|
||||||
|
type: "negative",
|
||||||
|
textColor: "white",
|
||||||
|
icon: "warning",
|
||||||
|
message: `Metaverse link attempt failed: ${result.responseJSON.error}`
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.$q.notify({
|
||||||
|
type: "negative",
|
||||||
|
textColor: "white",
|
||||||
|
icon: "warning",
|
||||||
|
message: `Login attempt failed: ${result.data.error}`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// TODO: This needs to go somewhere universal.
|
||||||
|
commitSettings (settingsToCommit) {
|
||||||
|
// TODO: This and all other URL endpoints should be in centralized (in their respective module) constants files.
|
||||||
|
return axios.post(`/settings.json`, JSON.stringify(settingsToCommit))
|
||||||
|
.then((response) => {
|
||||||
|
Log.info(Log.types.DOMAIN, `Successfully committed settings.`);
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.catch((response) => {
|
||||||
|
Log.error(Log.types.DOMAIN, `Failed to commit settings to Domain.`);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,3 +1,13 @@
|
||||||
|
<!--
|
||||||
|
// FirstTimeWizard.vue
|
||||||
|
//
|
||||||
|
// Created by Kalila L. on Sep. 4th, 2021.
|
||||||
|
// Copyright 2021 Vircadia contributors.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<q-layout id="vantaBG" view="hHh lpR fFf">
|
<q-layout id="vantaBG" view="hHh lpR fFf">
|
||||||
<q-page-container>
|
<q-page-container>
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
const Log = (function () {
|
const Log = (function () {
|
||||||
enum types {
|
enum types {
|
||||||
OTHER = "[OTHER]",
|
OTHER = "[OTHER]",
|
||||||
|
DOMAIN = "[DOMAIN]",
|
||||||
METAVERSE = "[METAVERSE]"
|
METAVERSE = "[METAVERSE]"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,25 +1,35 @@
|
||||||
|
<!--
|
||||||
|
// Index.vue
|
||||||
|
//
|
||||||
|
// Created by Kalila L. on Sep. 4th, 2021.
|
||||||
|
// Copyright 2021 Vircadia contributors.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="fullscreen bg-blue text-white text-center q-pa-md flex flex-center">
|
<div class="fullscreen bg-blue text-white text-center q-pa-md flex flex-center">
|
||||||
<div>
|
<div>
|
||||||
<div style="font-size: 30vh">
|
<div style="font-size: 30vh">
|
||||||
404
|
404
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="text-h2" style="opacity:.4">
|
<div class="text-h2" style="opacity:.4">
|
||||||
Oops. Nothing here...
|
Oops. Nothing here...
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<q-btn
|
<q-btn
|
||||||
class="q-mt-xl"
|
class="q-mt-xl"
|
||||||
color="white"
|
color="white"
|
||||||
text-color="blue"
|
text-color="blue"
|
||||||
unelevated
|
unelevated
|
||||||
to="/"
|
to="/"
|
||||||
label="Go Home"
|
label="Go Home"
|
||||||
no-caps
|
no-caps
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|
|
@ -1,3 +1,13 @@
|
||||||
|
<!--
|
||||||
|
// Index.vue
|
||||||
|
//
|
||||||
|
// Created by Kalila L. on Sep. 4th, 2021.
|
||||||
|
// Copyright 2021 Vircadia contributors.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
-->
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
$firstTimeWizardContainerBGstart: rgba(0, 0, 0, 0.0);
|
$firstTimeWizardContainerBGstart: rgba(0, 0, 0, 0.0);
|
||||||
$firstTimeWizardContainerBGend: rgba(0, 0, 0, 0.75);
|
$firstTimeWizardContainerBGend: rgba(0, 0, 0, 0.75);
|
||||||
|
@ -196,7 +206,7 @@
|
||||||
|
|
||||||
<q-step
|
<q-step
|
||||||
:name="4"
|
:name="4"
|
||||||
title="Metaverse"
|
:title="connectMetaverseSuccess ? 'Metaverse (Connected ✔️)' : 'Metaverse'"
|
||||||
caption="Optional"
|
caption="Optional"
|
||||||
:done="mainWizardStep > 4"
|
:done="mainWizardStep > 4"
|
||||||
>
|
>
|
||||||
|
@ -213,21 +223,22 @@
|
||||||
@click="connectMetaverseTriggered"
|
@click="connectMetaverseTriggered"
|
||||||
class="q-mb-md"
|
class="q-mb-md"
|
||||||
size="md"
|
size="md"
|
||||||
outline
|
:outline="!connectMetaverseSuccess"
|
||||||
|
:color="connectMetaverseSuccess ? 'green' : ''"
|
||||||
text-color="white"
|
text-color="white"
|
||||||
icon-right="cloud"
|
:icon-right="connectMetaverseSuccess ? 'done' : 'cloud'"
|
||||||
>
|
>
|
||||||
Connect
|
{{ connectMetaverseSuccess ? 'Connected' : 'Connect' }}
|
||||||
</q-btn>
|
</q-btn>
|
||||||
<q-btn
|
<q-btn
|
||||||
@click="$refs.stepper.next()"
|
@click="$refs.stepper.next()"
|
||||||
class="q-mb-md"
|
class="q-mb-md"
|
||||||
size="sm"
|
:size="connectMetaverseSuccess ? 'md' : 'sm'"
|
||||||
outline
|
outline
|
||||||
text-color="white"
|
text-color="white"
|
||||||
icon-right="chevron_right"
|
icon-right="chevron_right"
|
||||||
>
|
>
|
||||||
Skip
|
{{ connectMetaverseSuccess ? 'Next' : 'Skip' }}
|
||||||
</q-btn>
|
</q-btn>
|
||||||
<q-btn
|
<q-btn
|
||||||
@click="$refs.stepper.previous()"
|
@click="$refs.stepper.previous()"
|
||||||
|
@ -246,10 +257,46 @@
|
||||||
style="background: rgba(0, 0, 0, 0.95);"
|
style="background: rgba(0, 0, 0, 0.95);"
|
||||||
dark
|
dark
|
||||||
>
|
>
|
||||||
<ConnectMetaverse></ConnectMetaverse>
|
<ConnectMetaverse @connectionResult="onMetaverseConnectionAttempted"></ConnectMetaverse>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
</q-step>
|
</q-step>
|
||||||
|
|
||||||
|
<q-step
|
||||||
|
:name="5"
|
||||||
|
title="Security"
|
||||||
|
caption="Optional"
|
||||||
|
:done="mainWizardStep > 5"
|
||||||
|
>
|
||||||
|
<q-card
|
||||||
|
class="wizardCard"
|
||||||
|
>
|
||||||
|
<q-card-section>
|
||||||
|
<div class="text-h6 text-weight-light text-center">Let's configure some security settings for your world.</div>
|
||||||
|
</q-card-section>
|
||||||
|
|
||||||
|
<q-card-actions vertical align="right">
|
||||||
|
<q-btn
|
||||||
|
@click="saveSecuritySettings"
|
||||||
|
class="q-mb-md"
|
||||||
|
size="md"
|
||||||
|
outline
|
||||||
|
text-color="white"
|
||||||
|
icon-right="chevron_right"
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
</q-btn>
|
||||||
|
<q-btn
|
||||||
|
@click="$refs.stepper.previous()"
|
||||||
|
size="sm"
|
||||||
|
flat
|
||||||
|
icon-left="chevron_left"
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</q-btn>
|
||||||
|
</q-card-actions>
|
||||||
|
</q-card>
|
||||||
|
</q-step>
|
||||||
</q-stepper>
|
</q-stepper>
|
||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
|
@ -276,9 +323,11 @@ export default defineComponent({
|
||||||
welcomeText: true,
|
welcomeText: true,
|
||||||
mainWizard: true,
|
mainWizard: true,
|
||||||
mainWizardStep: ref(1),
|
mainWizardStep: ref(1),
|
||||||
|
// TODO: Needs to be based off of the actual state of the server's connection (using Vuex and retrieving settings on page load.)
|
||||||
|
connectMetaverseSuccess: true,
|
||||||
connectMetaverseDialog: false,
|
connectMetaverseDialog: false,
|
||||||
// Consts
|
// Consts
|
||||||
WELCOME_TEXT_TIMEOUT: 2000,
|
WELCOME_TEXT_TIMEOUT: 4000,
|
||||||
MAIN_WIZARD_TRANSITION_TIME: 1000,
|
MAIN_WIZARD_TRANSITION_TIME: 1000,
|
||||||
DEFAULT_METAVERSE_URL: "https://metaverse.vircadia.com/live"
|
DEFAULT_METAVERSE_URL: "https://metaverse.vircadia.com/live"
|
||||||
};
|
};
|
||||||
|
@ -293,6 +342,15 @@ export default defineComponent({
|
||||||
methods: {
|
methods: {
|
||||||
connectMetaverseTriggered () {
|
connectMetaverseTriggered () {
|
||||||
this.connectMetaverseDialog = true;
|
this.connectMetaverseDialog = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
onMetaverseConnectionAttempted () {
|
||||||
|
this.connectMetaverseSuccess = true;
|
||||||
|
this.mainWizardStep++;
|
||||||
|
},
|
||||||
|
|
||||||
|
saveSecuritySettings () {
|
||||||
|
// TODO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,15 @@
|
||||||
|
<!--
|
||||||
|
// Index.vue
|
||||||
|
//
|
||||||
|
// Created by Kalila L. on Sep. 4th, 2021.
|
||||||
|
// Copyright 2021 Vircadia contributors.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<h1>hi</h1>
|
<h1>Test</h1>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|
|
@ -1,3 +1,12 @@
|
||||||
|
// index.ts
|
||||||
|
//
|
||||||
|
// Created by Kalila L. on Sep. 4th, 2021.
|
||||||
|
// Copyright 2021 Vircadia contributors.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
|
||||||
|
|
||||||
import { route } from "quasar/wrappers";
|
import { route } from "quasar/wrappers";
|
||||||
import {
|
import {
|
||||||
createMemoryHistory,
|
createMemoryHistory,
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
// routes.ts
|
||||||
|
//
|
||||||
|
// Created by Kalila L. on Sep. 4th, 2021.
|
||||||
|
// Copyright 2021 Vircadia contributors.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
|
||||||
import { RouteRecordRaw } from "vue-router";
|
import { RouteRecordRaw } from "vue-router";
|
||||||
|
|
||||||
const routes: RouteRecordRaw[] = [
|
const routes: RouteRecordRaw[] = [
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
// index.ts
|
||||||
|
//
|
||||||
|
// Created by Kalila L. on Sep. 4th, 2021.
|
||||||
|
// Copyright 2021 Vircadia contributors.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
|
||||||
import { store } from "quasar/wrappers";
|
import { store } from "quasar/wrappers";
|
||||||
import { InjectionKey } from "vue";
|
import { InjectionKey } from "vue";
|
||||||
import {
|
import {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"extends": "@quasar/app/tsconfig-preset",
|
"extends": "@quasar/app/tsconfig-preset",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"baseUrl": "./web-new"
|
"baseUrl": "./web-new"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue