Merge branch 'refactor_wokas' into new_custom_woka_scene
230
.github/workflows/build-and-deploy.yml
vendored
@ -8,129 +8,235 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
types: [labeled, synchronize]
|
types: [labeled, synchronize]
|
||||||
|
|
||||||
|
|
||||||
# Enables BuildKit
|
|
||||||
env:
|
|
||||||
DOCKER_BUILDKIT: 1
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
build-front:
|
build-front:
|
||||||
if: ${{ github.event_name == 'push' || github.event_name == 'release' || github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'deploy') }}
|
if: ${{ github.event_name == 'push' || github.event_name == 'release' || github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'deploy') }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Setup NodeJS
|
||||||
# Create a slugified value of the branch
|
uses: actions/setup-node@v2
|
||||||
- uses: rlespinasse/github-slug-action@3.1.0
|
with:
|
||||||
|
node-version: '14'
|
||||||
- name: "Build and push front image"
|
|
||||||
uses: docker/build-push-action@v1
|
# messages
|
||||||
|
- name: Install messages dependencies
|
||||||
|
run: yarn install
|
||||||
|
working-directory: messages
|
||||||
|
|
||||||
|
- name: Build proto messages
|
||||||
|
run: yarn run ts-proto && yarn run copy-to-front-ts-proto && yarn run json-copy-to-front
|
||||||
|
working-directory: messages
|
||||||
|
|
||||||
|
# docker
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v1
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
|
||||||
|
- name: Login to DockerHub
|
||||||
|
uses: docker/login-action@v1
|
||||||
with:
|
with:
|
||||||
dockerfile: front/Dockerfile
|
|
||||||
path: ./
|
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
repository: thecodingmachine/workadventure-front
|
|
||||||
tags: ${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }}
|
- uses: rlespinasse/github-slug-action@3.1.0
|
||||||
add_git_labels: true
|
|
||||||
|
- name: Docker meta
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v3
|
||||||
|
with:
|
||||||
|
images: thecodingmachine/workadventure-front
|
||||||
|
|
||||||
|
- name: Build and push
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: front/Dockerfile
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
push: true
|
||||||
|
tags: thecodingmachine/workadventure-front:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
|
||||||
build-back:
|
build-back:
|
||||||
if: ${{ github.event_name == 'push' || github.event_name == 'release' || github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'deploy') }}
|
if: ${{ github.event_name == 'push' || github.event_name == 'release' || github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'deploy') }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
# Create a slugified value of the branch
|
- name: Setup NodeJS
|
||||||
- uses: rlespinasse/github-slug-action@3.1.0
|
uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
- name: "Build and push back image"
|
node-version: '14'
|
||||||
uses: docker/build-push-action@v1
|
|
||||||
|
# messages
|
||||||
|
- name: Install messages dependencies
|
||||||
|
run: yarn install
|
||||||
|
working-directory: messages
|
||||||
|
|
||||||
|
- name: Build proto messages
|
||||||
|
run: yarn run proto && yarn run copy-to-back && yarn run json-copy-to-back
|
||||||
|
working-directory: messages
|
||||||
|
|
||||||
|
# docker
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v1
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
|
||||||
|
- name: Login to DockerHub
|
||||||
|
uses: docker/login-action@v1
|
||||||
with:
|
with:
|
||||||
dockerfile: back/Dockerfile
|
|
||||||
path: ./
|
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
repository: thecodingmachine/workadventure-back
|
|
||||||
tags: ${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }}
|
- uses: rlespinasse/github-slug-action@3.1.0
|
||||||
add_git_labels: true
|
|
||||||
|
- name: Docker meta
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v3
|
||||||
|
with:
|
||||||
|
images: thecodingmachine/workadventure-back
|
||||||
|
|
||||||
|
- name: Build and push
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: back/Dockerfile
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
push: true
|
||||||
|
tags: thecodingmachine/workadventure-back:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
|
||||||
build-pusher:
|
build-pusher:
|
||||||
if: ${{ github.event_name == 'push' || github.event_name == 'release' || github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'deploy') }}
|
if: ${{ github.event_name == 'push' || github.event_name == 'release' || github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'deploy') }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
# Create a slugified value of the branch
|
- name: Setup NodeJS
|
||||||
- uses: rlespinasse/github-slug-action@3.1.0
|
uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
- name: "Build and push back image"
|
node-version: '14'
|
||||||
uses: docker/build-push-action@v1
|
|
||||||
|
# messages
|
||||||
|
- name: Install messages dependencies
|
||||||
|
run: yarn install
|
||||||
|
working-directory: messages
|
||||||
|
|
||||||
|
- name: Build proto messages
|
||||||
|
run: yarn run proto && yarn run copy-to-pusher && yarn run json-copy-to-pusher
|
||||||
|
working-directory: messages
|
||||||
|
|
||||||
|
# docker
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v1
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
|
||||||
|
- name: Login to DockerHub
|
||||||
|
uses: docker/login-action@v1
|
||||||
with:
|
with:
|
||||||
dockerfile: pusher/Dockerfile
|
|
||||||
path: ./
|
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
repository: thecodingmachine/workadventure-pusher
|
|
||||||
tags: ${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }}
|
- uses: rlespinasse/github-slug-action@3.1.0
|
||||||
add_git_labels: true
|
|
||||||
|
- name: Docker meta
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v3
|
||||||
|
with:
|
||||||
|
images: thecodingmachine/workadventure-pusher
|
||||||
|
|
||||||
|
- name: Build and push
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: pusher/Dockerfile
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
push: true
|
||||||
|
tags: thecodingmachine/workadventure-pusher:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
|
||||||
build-uploader:
|
build-uploader:
|
||||||
if: ${{ github.event_name == 'push' || github.event_name == 'release' || github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'deploy') }}
|
if: ${{ github.event_name == 'push' || github.event_name == 'release' || github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'deploy') }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v1
|
||||||
|
|
||||||
- name: Checkout
|
- name: Set up Docker Buildx
|
||||||
uses: actions/checkout@v2
|
uses: docker/setup-buildx-action@v1
|
||||||
|
|
||||||
# Create a slugified value of the branch
|
- name: Login to DockerHub
|
||||||
- uses: rlespinasse/github-slug-action@3.1.0
|
uses: docker/login-action@v1
|
||||||
|
|
||||||
- name: "Build and push back image"
|
|
||||||
uses: docker/build-push-action@v1
|
|
||||||
with:
|
with:
|
||||||
dockerfile: uploader/Dockerfile
|
|
||||||
path: ./
|
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
repository: thecodingmachine/workadventure-uploader
|
|
||||||
tags: ${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }}
|
- uses: rlespinasse/github-slug-action@3.1.0
|
||||||
add_git_labels: true
|
|
||||||
|
- name: Docker meta
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v3
|
||||||
|
with:
|
||||||
|
images: thecodingmachine/workadventure-uploader
|
||||||
|
|
||||||
|
- name: Build and push
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
file: uploader/Dockerfile
|
||||||
|
push: true
|
||||||
|
tags: thecodingmachine/workadventure-uploader:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
|
||||||
build-maps:
|
build-maps:
|
||||||
if: ${{ github.event_name == 'push' || github.event_name == 'release' || github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'deploy') }}
|
if: ${{ github.event_name == 'push' || github.event_name == 'release' || github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'deploy') }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v1
|
||||||
|
|
||||||
# Create a slugified value of the branch
|
- name: Set up Docker Buildx
|
||||||
- uses: rlespinasse/github-slug-action@3.1.0
|
uses: docker/setup-buildx-action@v1
|
||||||
|
|
||||||
- name: "Build and push front image"
|
- name: Login to DockerHub
|
||||||
uses: docker/build-push-action@v1
|
uses: docker/login-action@v1
|
||||||
with:
|
with:
|
||||||
dockerfile: maps/Dockerfile
|
|
||||||
path: maps/
|
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
repository: thecodingmachine/workadventure-maps
|
|
||||||
tags: ${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }}
|
- uses: rlespinasse/github-slug-action@3.1.0
|
||||||
add_git_labels: true
|
|
||||||
|
- name: Docker meta
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v3
|
||||||
|
with:
|
||||||
|
images: thecodingmachine/workadventure-maps
|
||||||
|
|
||||||
|
- name: Build and push
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: maps/
|
||||||
|
file: maps/Dockerfile
|
||||||
|
push: true
|
||||||
|
tags: thecodingmachine/workadventure-maps:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
|
||||||
deeploy:
|
deeploy:
|
||||||
needs:
|
needs:
|
||||||
|
104
.github/workflows/build-and-release-desktop.yml
vendored
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
name: Build & release desktop app
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
- develop
|
||||||
|
pull_request:
|
||||||
|
release:
|
||||||
|
types: [created]
|
||||||
|
|
||||||
|
env:
|
||||||
|
YARN_CACHE_FOLDER: ~/.yarn
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build_on_linux:
|
||||||
|
name: "Build & release desktop app for ${{ matrix.os }}"
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [14.x]
|
||||||
|
runtime: [ linux-x64, win-x64, osx-x64 ]
|
||||||
|
include:
|
||||||
|
- runtime: linux-x64
|
||||||
|
os: ubuntu-latest
|
||||||
|
|
||||||
|
- runtime: osx-x64
|
||||||
|
os: macos-latest
|
||||||
|
|
||||||
|
- runtime: win-x64
|
||||||
|
os: windows-latest
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: "Checkout"
|
||||||
|
uses: "actions/checkout@v2.0.0"
|
||||||
|
|
||||||
|
- name: "Setup NodeJS"
|
||||||
|
uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
|
|
||||||
|
- name: Caching
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
${{ env.YARN_CACHE_FOLDER }}
|
||||||
|
~/.cache/electron
|
||||||
|
~/.cache/electron-builder
|
||||||
|
key: ${{ runner.OS }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.OS }}-yarn-
|
||||||
|
|
||||||
|
- name: "local-app: Install dependencies"
|
||||||
|
run: yarn install --froze-lockfile
|
||||||
|
working-directory: "desktop/local-app"
|
||||||
|
|
||||||
|
- name: "local-app: Build"
|
||||||
|
run: yarn build
|
||||||
|
working-directory: "desktop/local-app"
|
||||||
|
|
||||||
|
- name: "Install dependencies"
|
||||||
|
run: yarn install --froze-lockfile
|
||||||
|
working-directory: "desktop/electron"
|
||||||
|
|
||||||
|
- name: "Build typescript"
|
||||||
|
run: yarn build
|
||||||
|
working-directory: "desktop/electron"
|
||||||
|
|
||||||
|
- name: "Build app"
|
||||||
|
run: yarn bundle --publish never
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
working-directory: "desktop/electron"
|
||||||
|
if: ${{ github.event_name != 'release' }}
|
||||||
|
|
||||||
|
- name: "Build & publish App"
|
||||||
|
run: yarn release
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
working-directory: "desktop/electron"
|
||||||
|
if: ${{ github.event_name == 'release' }}
|
||||||
|
|
||||||
|
- name: Upload Linux .AppImage artifact
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
if: startsWith(matrix.os, 'ubuntu')
|
||||||
|
with:
|
||||||
|
name: workadventure-desktop-linux-x64.AppImage
|
||||||
|
path: desktop/electron/build/workadventure-desktop-*-x86_64.AppImage
|
||||||
|
|
||||||
|
- name: Upload Windows .exe artifact
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
if: startsWith(matrix.os, 'windows')
|
||||||
|
with:
|
||||||
|
name: workadventure-desktop-win-x64.exe
|
||||||
|
path: desktop/electron/build/workadventure-desktop-*.exe
|
||||||
|
|
||||||
|
- name: Upload MacOS .dmg artifact
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
if: startsWith(matrix.os, 'macos')
|
||||||
|
with:
|
||||||
|
name: workadventure-mac.dmg
|
||||||
|
path: desktop/electron/build/workadventure-desktop-*.dmg
|
78
.github/workflows/continuous_integration.yml
vendored
@ -155,7 +155,7 @@ jobs:
|
|||||||
working-directory: "messages"
|
working-directory: "messages"
|
||||||
|
|
||||||
- name: "Build proto messages"
|
- name: "Build proto messages"
|
||||||
run: yarn run proto && yarn run copy-to-back
|
run: yarn run proto && yarn run copy-to-back && yarn run json-copy-to-back
|
||||||
working-directory: "messages"
|
working-directory: "messages"
|
||||||
|
|
||||||
- name: "Build"
|
- name: "Build"
|
||||||
@ -173,3 +173,79 @@ jobs:
|
|||||||
- name: "Prettier"
|
- name: "Prettier"
|
||||||
run: yarn run pretty-check
|
run: yarn run pretty-check
|
||||||
working-directory: "back"
|
working-directory: "back"
|
||||||
|
|
||||||
|
continuous-integration-desktop:
|
||||||
|
name: "Continuous Integration Desktop"
|
||||||
|
|
||||||
|
runs-on: "ubuntu-latest"
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: "Checkout"
|
||||||
|
uses: "actions/checkout@v2.0.0"
|
||||||
|
|
||||||
|
- name: "Setup NodeJS"
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: '14.x'
|
||||||
|
|
||||||
|
- name: "Install dependencies"
|
||||||
|
run: yarn install --froze-lockfile
|
||||||
|
working-directory: "desktop/electron"
|
||||||
|
|
||||||
|
- name: "Build"
|
||||||
|
run: yarn build
|
||||||
|
working-directory: "desktop/electron"
|
||||||
|
|
||||||
|
- name: "Typecheck"
|
||||||
|
run: yarn typecheck
|
||||||
|
working-directory: "desktop/electron"
|
||||||
|
|
||||||
|
- name: "Lint"
|
||||||
|
run: yarn lint
|
||||||
|
working-directory: "desktop/electron"
|
||||||
|
|
||||||
|
- name: "Jasmine"
|
||||||
|
run: yarn test
|
||||||
|
working-directory: "desktop/electron"
|
||||||
|
|
||||||
|
- name: "Prettier"
|
||||||
|
run: yarn pretty-check
|
||||||
|
working-directory: "desktop/electron"
|
||||||
|
|
||||||
|
continuous-integration-desktop-local-app:
|
||||||
|
name: "Continuous Integration Desktop Local App"
|
||||||
|
|
||||||
|
runs-on: "ubuntu-latest"
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: "Checkout"
|
||||||
|
uses: "actions/checkout@v2.0.0"
|
||||||
|
|
||||||
|
- name: "Setup NodeJS"
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: '14.x'
|
||||||
|
|
||||||
|
- name: "Install dependencies"
|
||||||
|
run: yarn install --froze-lockfile
|
||||||
|
working-directory: "desktop/local-app"
|
||||||
|
|
||||||
|
- name: "Build"
|
||||||
|
run: yarn build
|
||||||
|
working-directory: "desktop/local-app"
|
||||||
|
|
||||||
|
- name: "Typecheck"
|
||||||
|
run: yarn check
|
||||||
|
working-directory: "desktop/local-app"
|
||||||
|
|
||||||
|
- name: "Lint"
|
||||||
|
run: yarn lint
|
||||||
|
working-directory: "desktop/local-app"
|
||||||
|
|
||||||
|
- name: "Jasmine"
|
||||||
|
run: yarn test
|
||||||
|
working-directory: "desktop/local-app"
|
||||||
|
|
||||||
|
- name: "Prettier"
|
||||||
|
run: yarn pretty-check
|
||||||
|
working-directory: "desktop/local-app"
|
||||||
|
10
.github/workflows/end_to_end_tests.yml
vendored
@ -23,8 +23,16 @@ jobs:
|
|||||||
run: npx playwright install --with-deps
|
run: npx playwright install --with-deps
|
||||||
- name: 'Setup .env file'
|
- name: 'Setup .env file'
|
||||||
run: cp .env.template .env
|
run: cp .env.template .env
|
||||||
|
- name: Install messages dependencies
|
||||||
|
run: yarn install
|
||||||
|
working-directory: messages
|
||||||
|
- name: Build proto messages
|
||||||
|
run: yarn run proto-all
|
||||||
|
working-directory: messages
|
||||||
|
- name: Build WorkAdventure
|
||||||
|
run: docker-compose -f docker-compose.yaml -f docker-compose.e2e.yml build --parallel
|
||||||
- name: Start WorkAdventure
|
- name: Start WorkAdventure
|
||||||
run: docker-compose -f docker-compose.yaml -f docker-compose.e2e.yml up -d --build
|
run: docker-compose -f docker-compose.yaml -f docker-compose.e2e.yml up -d
|
||||||
- name: Wait for environment to Start
|
- name: Wait for environment to Start
|
||||||
run: sleep 60
|
run: sleep 60
|
||||||
- name: Run Playwright tests
|
- name: Run Playwright tests
|
||||||
|
@ -28,7 +28,7 @@ You can use [GitHub issue tracker](https://github.com/thecodingmachine/workadven
|
|||||||
- File bug reports
|
- File bug reports
|
||||||
- Ask for feature requests
|
- Ask for feature requests
|
||||||
|
|
||||||
If you have more general questions, a good place to ask is [our Discord server](https://discord.gg/YGtngdh9gt).
|
If you have more general questions, a good place to ask is [our Discord server](https://discord.gg/G6Xh9ZM9aR).
|
||||||
|
|
||||||
Finally, you can come and talk to the WorkAdventure core team... on WorkAdventure, of course! [Our offices are here](https://play.staging.workadventu.re/@/tcm/workadventure/wa-village).
|
Finally, you can come and talk to the WorkAdventure core team... on WorkAdventure, of course! [Our offices are here](https://play.staging.workadventu.re/@/tcm/workadventure/wa-village).
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ Please ask first before embarking on any significant pull request (e.g. implemen
|
|||||||
otherwise you risk spending a lot of time working on something that the project's developers might not want to merge
|
otherwise you risk spending a lot of time working on something that the project's developers might not want to merge
|
||||||
into the project.
|
into the project.
|
||||||
|
|
||||||
You can ask us on [Discord](https://discord.gg/YGtngdh9gt) or in the [GitHub issues](https://github.com/thecodingmachine/workadventure/issues).
|
You can ask us on [Discord](https://discord.gg/G6Xh9ZM9aR) or in the [GitHub issues](https://github.com/thecodingmachine/workadventure/issues).
|
||||||
|
|
||||||
### Linting your code
|
### Linting your code
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
![](https://github.com/thecodingmachine/workadventure/workflows/Continuous%20Integration/badge.svg) [![Discord](https://img.shields.io/discord/821338762134290432?label=Discord)](https://discord.gg/YGtngdh9gt)
|
![](https://github.com/thecodingmachine/workadventure/workflows/Continuous%20Integration/badge.svg) [![Discord](https://img.shields.io/discord/821338762134290432?label=Discord)](https://discord.gg/G6Xh9ZM9aR)
|
||||||
|
|
||||||
![WorkAdventure logo](README-LOGO.svg)
|
![WorkAdventure logo](README-LOGO.svg)
|
||||||
![WorkAdventure office image](README-MAP.png)
|
![WorkAdventure office image](README-MAP.png)
|
||||||
|
@ -1,16 +1,22 @@
|
|||||||
|
# The building of ProtoBuf "messages" must be done out of Docker because grpc-node does not ship with ARM64 binaries.
|
||||||
|
# See: https://github.com/grpc/grpc-node/issues/1405
|
||||||
|
# When the issue above is closed, we can move back messages building inside Dockerfile
|
||||||
|
|
||||||
# protobuf build
|
# protobuf build
|
||||||
FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as builder
|
#FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as proto-builder
|
||||||
WORKDIR /usr/src
|
#WORKDIR /usr/src
|
||||||
COPY messages .
|
#COPY messages/yarn.lock messages/package.json ./
|
||||||
RUN yarn install && yarn proto
|
#RUN yarn install
|
||||||
|
#COPY messages .
|
||||||
|
#RUN yarn proto
|
||||||
|
|
||||||
# typescript build
|
# typescript build
|
||||||
FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as builder2
|
FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as builder
|
||||||
WORKDIR /usr/src
|
WORKDIR /usr/src
|
||||||
COPY back/yarn.lock back/package.json ./
|
COPY back/yarn.lock back/package.json ./
|
||||||
RUN yarn install
|
RUN yarn install
|
||||||
COPY back .
|
COPY back .
|
||||||
COPY --from=builder /usr/src/generated src/Messages/generated
|
#COPY --from=proto-builder /usr/src/generated src/Messages/generated
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
RUN yarn run tsc
|
RUN yarn run tsc
|
||||||
|
|
||||||
@ -18,9 +24,9 @@ RUN yarn run tsc
|
|||||||
FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d
|
FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d
|
||||||
WORKDIR /usr/src
|
WORKDIR /usr/src
|
||||||
COPY back/yarn.lock back/package.json ./
|
COPY back/yarn.lock back/package.json ./
|
||||||
COPY --from=builder2 /usr/src/dist /usr/src/dist
|
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
RUN yarn install --production
|
RUN yarn install --production
|
||||||
|
COPY --from=builder /usr/src/dist /usr/src/dist
|
||||||
|
|
||||||
USER node
|
USER node
|
||||||
CMD ["yarn", "run", "runprod"]
|
CMD ["yarn", "run", "runprod"]
|
||||||
|
@ -43,6 +43,15 @@ class MapFetcher {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
async isLocalUrl(url: string): Promise<boolean> {
|
async isLocalUrl(url: string): Promise<boolean> {
|
||||||
|
if (
|
||||||
|
url ===
|
||||||
|
"http://play.workadventure.localhost/_/global/maps.workadventure.localhost/tests/Variables/shared_variables.json"
|
||||||
|
) {
|
||||||
|
// This is an ugly exception case needed for the E2E test at "tests/tests/variables.spec.ts"
|
||||||
|
// Otherwise, we cannot test locally maps that are... not local.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const urlObj = new URL(url);
|
const urlObj = new URL(url);
|
||||||
if (urlObj.hostname === "localhost" || urlObj.hostname.endsWith(".localhost")) {
|
if (urlObj.hostname === "localhost" || urlObj.hostname.endsWith(".localhost")) {
|
||||||
return true;
|
return true;
|
||||||
|
691
desktop/LICENSE.txt
Normal file
@ -0,0 +1,691 @@
|
|||||||
|
NOTICE
|
||||||
|
This package contains software licensed under different
|
||||||
|
licenses, please refer to the NOTICE.txt file for further
|
||||||
|
information and LICENSES.txt for full license texts.
|
||||||
|
|
||||||
|
WorkAdventure Enterprise edition can be licensed independently from
|
||||||
|
the source under separate commercial terms.
|
||||||
|
|
||||||
|
The software ("Software") is developed and owned by TheCodingMachine
|
||||||
|
and is subject to the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, with the Commons Clause as follows:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 19 November 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU Affero General Public License is a free, copyleft license
|
||||||
|
for software and other kinds of works, specifically designed to ensure
|
||||||
|
cooperation with the community in the case of network server software.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are
|
||||||
|
designed to take away your freedom to share and change the works. By
|
||||||
|
contrast, our General Public Licenses are intended to guarantee your
|
||||||
|
freedom to share and change all versions of a program--to make sure it
|
||||||
|
remains free software for all its users.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
them if you wish), that you receive source code or can get it if you
|
||||||
|
want it, that you can change the software or use pieces of it in new
|
||||||
|
free programs, and that you know you can do these things.
|
||||||
|
|
||||||
|
Developers that use our General Public Licenses protect your rights
|
||||||
|
with two steps: (1) assert copyright on the software, and (2) offer
|
||||||
|
you this License which gives you legal permission to copy, distribute
|
||||||
|
and/or modify the software.
|
||||||
|
|
||||||
|
A secondary benefit of defending all users' freedom is that
|
||||||
|
improvements made in alternate versions of the program, if they
|
||||||
|
receive widespread use, become available for other developers to
|
||||||
|
incorporate. Many developers of free software are heartened and
|
||||||
|
encouraged by the resulting cooperation. However, in the case of
|
||||||
|
software used on network servers, this result may fail to come about.
|
||||||
|
The GNU General Public License permits making a modified version and
|
||||||
|
letting the public access it on a server without ever releasing its
|
||||||
|
source code to the public.
|
||||||
|
|
||||||
|
The GNU Affero General Public License is designed specifically to
|
||||||
|
ensure that, in such cases, the modified source code becomes available
|
||||||
|
to the community. It requires the operator of a network server to
|
||||||
|
provide the source code of the modified version running there to the
|
||||||
|
users of that server. Therefore, public use of a modified version, on
|
||||||
|
a publicly accessible server, gives the public access to the source
|
||||||
|
code of the modified version.
|
||||||
|
|
||||||
|
An older license, called the Affero General Public License and
|
||||||
|
published by Affero, was designed to accomplish similar goals. This is
|
||||||
|
a different license, not a version of the Affero GPL, but Affero has
|
||||||
|
released a new version of the Affero GPL which permits relicensing under
|
||||||
|
this license.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU Affero General Public
|
||||||
|
License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds
|
||||||
|
of works, such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
|
"recipients" may be individuals or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work
|
||||||
|
in a fashion requiring copyright permission, other than the making of an
|
||||||
|
exact copy. The resulting work is called a "modified version" of the
|
||||||
|
earlier work or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based
|
||||||
|
on the Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without
|
||||||
|
permission, would make you directly or secondarily liable for
|
||||||
|
infringement under applicable copyright law, except executing it on a
|
||||||
|
computer or modifying a private copy. Propagation includes copying,
|
||||||
|
distribution (with or without modification), making available to the
|
||||||
|
public, and in some countries other activities as well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other
|
||||||
|
parties to make or receive copies. Mere interaction with a user through
|
||||||
|
a computer network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices"
|
||||||
|
to the extent that it includes a convenient and prominently visible
|
||||||
|
feature that (1) displays an appropriate copyright notice, and (2)
|
||||||
|
tells the user that there is no warranty for the work (except to the
|
||||||
|
extent that warranties are provided), that licensees may convey the
|
||||||
|
work under this License, and how to view a copy of this License. If
|
||||||
|
the interface presents a list of user commands or options, such as a
|
||||||
|
menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work
|
||||||
|
for making modifications to it. "Object code" means any non-source
|
||||||
|
form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official
|
||||||
|
standard defined by a recognized standards body, or, in the case of
|
||||||
|
interfaces specified for a particular programming language, one that
|
||||||
|
is widely used among developers working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other
|
||||||
|
than the work as a whole, that (a) is included in the normal form of
|
||||||
|
packaging a Major Component, but which is not part of that Major
|
||||||
|
Component, and (b) serves only to enable use of the work with that
|
||||||
|
Major Component, or to implement a Standard Interface for which an
|
||||||
|
implementation is available to the public in source code form. A
|
||||||
|
"Major Component", in this context, means a major essential component
|
||||||
|
(kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to
|
||||||
|
produce the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all
|
||||||
|
the source code needed to generate, install, and (for an executable
|
||||||
|
work) run the object code and to modify the work, including scripts to
|
||||||
|
control those activities. However, it does not include the work's
|
||||||
|
System Libraries, or general-purpose tools or generally available free
|
||||||
|
programs which are used unmodified in performing those activities but
|
||||||
|
which are not part of the work. For example, Corresponding Source
|
||||||
|
includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically
|
||||||
|
linked subprograms that the work is specifically designed to require,
|
||||||
|
such as by intimate data communication or control flow between those
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users
|
||||||
|
can regenerate automatically from other parts of the Corresponding
|
||||||
|
Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that
|
||||||
|
same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of
|
||||||
|
copyright on the Program, and are irrevocable provided the stated
|
||||||
|
conditions are met. This License explicitly affirms your unlimited
|
||||||
|
permission to run the unmodified Program. The output from running a
|
||||||
|
covered work is covered by this License only if the output, given its
|
||||||
|
content, constitutes a covered work. This License acknowledges your
|
||||||
|
rights of fair use or other equivalent, as provided by copyright law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not
|
||||||
|
convey, without conditions so long as your license otherwise remains
|
||||||
|
in force. You may convey covered works to others for the sole purpose
|
||||||
|
of having them make modifications exclusively for you, or provide you
|
||||||
|
with facilities for running those works, provided that you comply with
|
||||||
|
the terms of this License in conveying all material for which you do
|
||||||
|
not control copyright. Those thus making or running the covered works
|
||||||
|
for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of
|
||||||
|
your copyrighted material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under
|
||||||
|
the conditions stated below. Sublicensing is not allowed; section 10
|
||||||
|
makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological
|
||||||
|
measure under any applicable law fulfilling obligations under article
|
||||||
|
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||||
|
similar laws prohibiting or restricting circumvention of such
|
||||||
|
measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid
|
||||||
|
circumvention of technological measures to the extent such circumvention
|
||||||
|
is effected by exercising rights under this License with respect to
|
||||||
|
the covered work, and you disclaim any intention to limit operation or
|
||||||
|
modification of the work as a means of enforcing, against the work's
|
||||||
|
users, your or third parties' legal rights to forbid circumvention of
|
||||||
|
technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey verbatim copies of the Program's source code as you
|
||||||
|
receive it, in any medium, provided that you conspicuously and
|
||||||
|
appropriately publish on each copy an appropriate copyright notice;
|
||||||
|
keep intact all notices stating that this License and any
|
||||||
|
non-permissive terms added in accord with section 7 apply to the code;
|
||||||
|
keep intact all notices of the absence of any warranty; and give all
|
||||||
|
recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey,
|
||||||
|
and you may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to
|
||||||
|
produce it from the Program, in the form of source code under the
|
||||||
|
terms of section 4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified
|
||||||
|
it, and giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is
|
||||||
|
released under this License and any conditions added under section
|
||||||
|
7. This requirement modifies the requirement in section 4 to
|
||||||
|
"keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this
|
||||||
|
License to anyone who comes into possession of a copy. This
|
||||||
|
License will therefore apply, along with any applicable section 7
|
||||||
|
additional terms, to the whole of the work, and all its parts,
|
||||||
|
regardless of how they are packaged. This License gives no
|
||||||
|
permission to license the work in any other way, but it does not
|
||||||
|
invalidate such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display
|
||||||
|
Appropriate Legal Notices; however, if the Program has interactive
|
||||||
|
interfaces that do not display Appropriate Legal Notices, your
|
||||||
|
work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent
|
||||||
|
works, which are not by their nature extensions of the covered work,
|
||||||
|
and which are not combined with it such as to form a larger program,
|
||||||
|
in or on a volume of a storage or distribution medium, is called an
|
||||||
|
"aggregate" if the compilation and its resulting copyright are not
|
||||||
|
used to limit the access or legal rights of the compilation's users
|
||||||
|
beyond what the individual works permit. Inclusion of a covered work
|
||||||
|
in an aggregate does not cause this License to apply to the other
|
||||||
|
parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms
|
||||||
|
of sections 4 and 5, provided that you also convey the
|
||||||
|
machine-readable Corresponding Source under the terms of this License,
|
||||||
|
in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by the
|
||||||
|
Corresponding Source fixed on a durable physical medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by a
|
||||||
|
written offer, valid for at least three years and valid for as
|
||||||
|
long as you offer spare parts or customer support for that product
|
||||||
|
model, to give anyone who possesses the object code either (1) a
|
||||||
|
copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical
|
||||||
|
medium customarily used for software interchange, for a price no
|
||||||
|
more than your reasonable cost of physically performing this
|
||||||
|
conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the
|
||||||
|
written offer to provide the Corresponding Source. This
|
||||||
|
alternative is allowed only occasionally and noncommercially, and
|
||||||
|
only if you received the object code with such an offer, in accord
|
||||||
|
with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated
|
||||||
|
place (gratis or for a charge), and offer equivalent access to the
|
||||||
|
Corresponding Source in the same way through the same place at no
|
||||||
|
further charge. You need not require recipients to copy the
|
||||||
|
Corresponding Source along with the object code. If the place to
|
||||||
|
copy the object code is a network server, the Corresponding Source
|
||||||
|
may be on a different server (operated by you or a third party)
|
||||||
|
that supports equivalent copying facilities, provided you maintain
|
||||||
|
clear directions next to the object code saying where to find the
|
||||||
|
Corresponding Source. Regardless of what server hosts the
|
||||||
|
Corresponding Source, you remain obligated to ensure that it is
|
||||||
|
available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided
|
||||||
|
you inform other peers where the object code and Corresponding
|
||||||
|
Source of the work are being offered to the general public at no
|
||||||
|
charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded
|
||||||
|
from the Corresponding Source as a System Library, need not be
|
||||||
|
included in conveying the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any
|
||||||
|
tangible personal property which is normally used for personal, family,
|
||||||
|
or household purposes, or (2) anything designed or sold for incorporation
|
||||||
|
into a dwelling. In determining whether a product is a consumer product,
|
||||||
|
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||||
|
product received by a particular user, "normally used" refers to a
|
||||||
|
typical or common use of that class of product, regardless of the status
|
||||||
|
of the particular user or of the way in which the particular user
|
||||||
|
actually uses, or expects or is expected to use, the product. A product
|
||||||
|
is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent
|
||||||
|
the only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods,
|
||||||
|
procedures, authorization keys, or other information required to install
|
||||||
|
and execute modified versions of a covered work in that User Product from
|
||||||
|
a modified version of its Corresponding Source. The information must
|
||||||
|
suffice to ensure that the continued functioning of the modified object
|
||||||
|
code is in no case prevented or interfered with solely because
|
||||||
|
modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or
|
||||||
|
specifically for use in, a User Product, and the conveying occurs as
|
||||||
|
part of a transaction in which the right of possession and use of the
|
||||||
|
User Product is transferred to the recipient in perpetuity or for a
|
||||||
|
fixed term (regardless of how the transaction is characterized), the
|
||||||
|
Corresponding Source conveyed under this section must be accompanied
|
||||||
|
by the Installation Information. But this requirement does not apply
|
||||||
|
if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has
|
||||||
|
been installed in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a
|
||||||
|
requirement to continue to provide support service, warranty, or updates
|
||||||
|
for a work that has been modified or installed by the recipient, or for
|
||||||
|
the User Product in which it has been modified or installed. Access to a
|
||||||
|
network may be denied when the modification itself materially and
|
||||||
|
adversely affects the operation of the network or violates the rules and
|
||||||
|
protocols for communication across the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided,
|
||||||
|
in accord with this section must be in a format that is publicly
|
||||||
|
documented (and with an implementation available to the public in
|
||||||
|
source code form), and must require no special password or key for
|
||||||
|
unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this
|
||||||
|
License by making exceptions from one or more of its conditions.
|
||||||
|
Additional permissions that are applicable to the entire Program shall
|
||||||
|
be treated as though they were included in this License, to the extent
|
||||||
|
that they are valid under applicable law. If additional permissions
|
||||||
|
apply only to part of the Program, that part may be used separately
|
||||||
|
under those permissions, but the entire Program remains governed by
|
||||||
|
this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option
|
||||||
|
remove any additional permissions from that copy, or from any part of
|
||||||
|
it. (Additional permissions may be written to require their own
|
||||||
|
removal in certain cases when you modify the work.) You may place
|
||||||
|
additional permissions on material, added by you to a covered work,
|
||||||
|
for which you have or can give appropriate copyright permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you
|
||||||
|
add to a covered work, you may (if authorized by the copyright holders of
|
||||||
|
that material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the
|
||||||
|
terms of sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or
|
||||||
|
author attributions in that material or in the Appropriate Legal
|
||||||
|
Notices displayed by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or
|
||||||
|
requiring that modified versions of such material be marked in
|
||||||
|
reasonable ways as different from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or
|
||||||
|
authors of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some
|
||||||
|
trade names, trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that
|
||||||
|
material by anyone who conveys the material (or modified versions of
|
||||||
|
it) with contractual assumptions of liability to the recipient, for
|
||||||
|
any liability that these contractual assumptions directly impose on
|
||||||
|
those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further
|
||||||
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
|
received it, or any part of it, contains a notice stating that it is
|
||||||
|
governed by this License along with a term that is a further restriction,
|
||||||
|
you may remove that term. If a license document contains a further
|
||||||
|
restriction but permits relicensing or conveying under this License, you
|
||||||
|
may add to a covered work material governed by the terms of that license
|
||||||
|
document, provided that the further restriction does not survive such
|
||||||
|
relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you
|
||||||
|
must place, in the relevant source files, a statement of the
|
||||||
|
additional terms that apply to those files, or a notice indicating
|
||||||
|
where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the
|
||||||
|
form of a separately written license, or stated as exceptions;
|
||||||
|
the above requirements apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly
|
||||||
|
provided under this License. Any attempt otherwise to propagate or
|
||||||
|
modify it is void, and will automatically terminate your rights under
|
||||||
|
this License (including any patent licenses granted under the third
|
||||||
|
paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your
|
||||||
|
license from a particular copyright holder is reinstated (a)
|
||||||
|
provisionally, unless and until the copyright holder explicitly and
|
||||||
|
finally terminates your license, and (b) permanently, if the copyright
|
||||||
|
holder fails to notify you of the violation by some reasonable means
|
||||||
|
prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is
|
||||||
|
reinstated permanently if the copyright holder notifies you of the
|
||||||
|
violation by some reasonable means, this is the first time you have
|
||||||
|
received notice of violation of this License (for any work) from that
|
||||||
|
copyright holder, and you cure the violation prior to 30 days after
|
||||||
|
your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the
|
||||||
|
licenses of parties who have received copies or rights from you under
|
||||||
|
this License. If your rights have been terminated and not permanently
|
||||||
|
reinstated, you do not qualify to receive new licenses for the same
|
||||||
|
material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or
|
||||||
|
run a copy of the Program. Ancillary propagation of a covered work
|
||||||
|
occurring solely as a consequence of using peer-to-peer transmission
|
||||||
|
to receive a copy likewise does not require acceptance. However,
|
||||||
|
nothing other than this License grants you permission to propagate or
|
||||||
|
modify any covered work. These actions infringe copyright if you do
|
||||||
|
not accept this License. Therefore, by modifying or propagating a
|
||||||
|
covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically
|
||||||
|
receives a license from the original licensors, to run, modify and
|
||||||
|
propagate that work, subject to this License. You are not responsible
|
||||||
|
for enforcing compliance by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an
|
||||||
|
organization, or substantially all assets of one, or subdividing an
|
||||||
|
organization, or merging organizations. If propagation of a covered
|
||||||
|
work results from an entity transaction, each party to that
|
||||||
|
transaction who receives a copy of the work also receives whatever
|
||||||
|
licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the
|
||||||
|
Corresponding Source of the work from the predecessor in interest, if
|
||||||
|
the predecessor has it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the
|
||||||
|
rights granted or affirmed under this License. For example, you may
|
||||||
|
not impose a license fee, royalty, or other charge for exercise of
|
||||||
|
rights granted under this License, and you may not initiate litigation
|
||||||
|
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||||
|
any patent claim is infringed by making, using, selling, offering for
|
||||||
|
sale, or importing the Program or any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this
|
||||||
|
License of the Program or a work on which the Program is based. The
|
||||||
|
work thus licensed is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims
|
||||||
|
owned or controlled by the contributor, whether already acquired or
|
||||||
|
hereafter acquired, that would be infringed by some manner, permitted
|
||||||
|
by this License, of making, using, or selling its contributor version,
|
||||||
|
but do not include claims that would be infringed only as a
|
||||||
|
consequence of further modification of the contributor version. For
|
||||||
|
purposes of this definition, "control" includes the right to grant
|
||||||
|
patent sublicenses in a manner consistent with the requirements of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||||
|
patent license under the contributor's essential patent claims, to
|
||||||
|
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||||
|
propagate the contents of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express
|
||||||
|
agreement or commitment, however denominated, not to enforce a patent
|
||||||
|
(such as an express permission to practice a patent or covenant not to
|
||||||
|
sue for patent infringement). To "grant" such a patent license to a
|
||||||
|
party means to make such an agreement or commitment not to enforce a
|
||||||
|
patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license,
|
||||||
|
and the Corresponding Source of the work is not available for anyone
|
||||||
|
to copy, free of charge and under the terms of this License, through a
|
||||||
|
publicly available network server or other readily accessible means,
|
||||||
|
then you must either (1) cause the Corresponding Source to be so
|
||||||
|
available, or (2) arrange to deprive yourself of the benefit of the
|
||||||
|
patent license for this particular work, or (3) arrange, in a manner
|
||||||
|
consistent with the requirements of this License, to extend the patent
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have
|
||||||
|
actual knowledge that, but for the patent license, your conveying the
|
||||||
|
covered work in a country, or your recipient's use of the covered work
|
||||||
|
in a country, would infringe one or more identifiable patents in that
|
||||||
|
country that you have reason to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or
|
||||||
|
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||||
|
covered work, and grant a patent license to some of the parties
|
||||||
|
receiving the covered work authorizing them to use, propagate, modify
|
||||||
|
or convey a specific copy of the covered work, then the patent license
|
||||||
|
you grant is automatically extended to all recipients of the covered
|
||||||
|
work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within
|
||||||
|
the scope of its coverage, prohibits the exercise of, or is
|
||||||
|
conditioned on the non-exercise of one or more of the rights that are
|
||||||
|
specifically granted under this License. You may not convey a covered
|
||||||
|
work if you are a party to an arrangement with a third party that is
|
||||||
|
in the business of distributing software, under which you make payment
|
||||||
|
to the third party based on the extent of your activity of conveying
|
||||||
|
the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory
|
||||||
|
patent license (a) in connection with copies of the covered work
|
||||||
|
conveyed by you (or copies made from those copies), or (b) primarily
|
||||||
|
for and in connection with specific products or compilations that
|
||||||
|
contain the covered work, unless you entered into that arrangement,
|
||||||
|
or that patent license was granted, prior to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting
|
||||||
|
any implied license or other defenses to infringement that may
|
||||||
|
otherwise be available to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot convey a
|
||||||
|
covered work so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you may
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey
|
||||||
|
the Program, the only way you could satisfy both those terms and this
|
||||||
|
License would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, if you modify the
|
||||||
|
Program, your modified version must prominently offer all users
|
||||||
|
interacting with it remotely through a computer network (if your version
|
||||||
|
supports such interaction) an opportunity to receive the Corresponding
|
||||||
|
Source of your version by providing access to the Corresponding Source
|
||||||
|
from a network server at no charge, through some standard or customary
|
||||||
|
means of facilitating copying of software. This Corresponding Source
|
||||||
|
shall include the Corresponding Source for any work covered by version 3
|
||||||
|
of the GNU General Public License that is incorporated pursuant to the
|
||||||
|
following paragraph.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have permission
|
||||||
|
to link or combine any covered work with a work licensed under version 3
|
||||||
|
of the GNU General Public License into a single combined work, and to
|
||||||
|
convey the resulting work. The terms of this License will continue to
|
||||||
|
apply to the part which is the covered work, but the work with which it is
|
||||||
|
combined will remain governed by version 3 of the GNU General Public
|
||||||
|
License.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the GNU Affero General Public License from time to time. Such new
|
||||||
|
versions will be similar in spirit to the present version, but may differ
|
||||||
|
in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Program specifies that a certain numbered version of the GNU Affero
|
||||||
|
General Public License "or any later version" applies to it, you have
|
||||||
|
the option of following the terms and conditions either of that
|
||||||
|
numbered version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number
|
||||||
|
of the GNU Affero General Public License, you may choose any version
|
||||||
|
ever published by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future
|
||||||
|
versions of the GNU Affero General Public License can be used, that
|
||||||
|
proxy's public statement of acceptance of a version permanently
|
||||||
|
authorizes you to choose that version for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different
|
||||||
|
permissions. However, no additional obligations are imposed on any
|
||||||
|
author or copyright holder as a result of your choosing to follow a
|
||||||
|
later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||||
|
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||||
|
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||||
|
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||||
|
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||||
|
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||||
|
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||||
|
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||||
|
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||||
|
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||||
|
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||||
|
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGES.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided
|
||||||
|
above cannot be given local legal effect according to their terms,
|
||||||
|
reviewing courts shall apply local law that most closely approximates
|
||||||
|
an absolute waiver of all civil liability in connection with the
|
||||||
|
Program, unless a warranty or assumption of liability accompanies a
|
||||||
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
state the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of the
|
||||||
|
License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If your software can interact with users remotely through a computer
|
||||||
|
network, you should also make sure that it provides a way for users to
|
||||||
|
get its source. For example, if your program is a web application, its
|
||||||
|
interface could display a "Source" link that leads users to an archive
|
||||||
|
of the code. There are many ways you could offer source, and different
|
||||||
|
solutions will be better for different programs; see section 13 for the
|
||||||
|
specific requirements.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
|
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
"Commons Clause" License Condition
|
||||||
|
|
||||||
|
The Software is provided to you by the Licensor under the License, as
|
||||||
|
defined below, subject to the following condition. Without limiting
|
||||||
|
other conditions in the License, the grant of rights under the License
|
||||||
|
will not include, and the License does not grant to you, the right to
|
||||||
|
Sell the Software. For purposes of the foregoing, "Sell" means
|
||||||
|
practicing any or all of the rights granted to you under the License
|
||||||
|
to provide to third parties, for a fee or other consideration,
|
||||||
|
a product or service that consists, entirely or substantially,
|
||||||
|
of the Software or the functionality of the Software. Any license
|
||||||
|
notice or attribution required by the License must also include
|
||||||
|
this Commons Cause License Condition notice.
|
46
desktop/README.md
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# Desktop app
|
||||||
|
|
||||||
|
The desktop component is an electron app inside `./electron/`. It uses a hybrid setup based of two main components:
|
||||||
|
- A `local-app` bundled into the electron app with two main parts:
|
||||||
|
- A sidebar to show the server list, with the currently selected server
|
||||||
|
- A main page which is used to manage servers and to show other "local" pages like the desktop-app settings
|
||||||
|
- A BrowserView (often called `appView` or `app`) showing the actual frontend of an external WorkAdventure deployment.
|
||||||
|
If a server is selected the BrowserView / `appView` is overlaying the whole main part right to the sidebar.
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# start local-app in watch mode
|
||||||
|
cd local-app && yarn dev
|
||||||
|
|
||||||
|
# start electron app in watch mode
|
||||||
|
cd electron && LOCAL_APP_URL=http://localhost:3000 yarn dev
|
||||||
|
|
||||||
|
# or create an executable by running:
|
||||||
|
cd electron && yarn bundle
|
||||||
|
```
|
||||||
|
|
||||||
|
## API for front
|
||||||
|
|
||||||
|
TODO:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
if (window?.WorkAdventureDesktopApi?.desktop) {
|
||||||
|
alert('Yeah you are using the desktop app ;)');
|
||||||
|
}
|
||||||
|
|
||||||
|
let muted = false;
|
||||||
|
|
||||||
|
window?.WorkAdventureDesktopApi?.onMutedKeyPress((event) => {
|
||||||
|
if (muted) {
|
||||||
|
document.getElementById("info-box").innerHTML =
|
||||||
|
"Ready to speak! Press ctrl-alt-m to mute.";
|
||||||
|
} else {
|
||||||
|
document.getElementById("info-box").innerHTML =
|
||||||
|
"Muted! Press ctrl-alt-m to unmute again.";
|
||||||
|
}
|
||||||
|
muted = !muted;
|
||||||
|
});
|
||||||
|
|
||||||
|
window.WorkAdventureDesktopApi.notify("Hello from front");
|
||||||
|
```
|
30
desktop/electron/.eslintrc.json
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"root": true,
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"es6": true,
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
|
"extends": [
|
||||||
|
"eslint:recommended",
|
||||||
|
"plugin:@typescript-eslint/eslint-recommended",
|
||||||
|
"plugin:@typescript-eslint/recommended-requiring-type-checking"
|
||||||
|
],
|
||||||
|
"globals": {
|
||||||
|
"Atomics": "readonly",
|
||||||
|
"SharedArrayBuffer": "readonly"
|
||||||
|
},
|
||||||
|
"parser": "@typescript-eslint/parser",
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 2018,
|
||||||
|
"sourceType": "module",
|
||||||
|
"project": "./tsconfig.json"
|
||||||
|
},
|
||||||
|
"plugins": [
|
||||||
|
"@typescript-eslint"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"no-unused-vars": "off",
|
||||||
|
"@typescript-eslint/no-explicit-any": "error"
|
||||||
|
}
|
||||||
|
}
|
4
desktop/electron/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
/dist/
|
||||||
|
/node_modules/
|
||||||
|
/yarn-error.log
|
||||||
|
/build/
|
1
desktop/electron/.prettierignore
Normal file
@ -0,0 +1 @@
|
|||||||
|
src/Messages/generated
|
4
desktop/electron/.prettierrc.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"printWidth": 120,
|
||||||
|
"tabWidth": 4
|
||||||
|
}
|
BIN
desktop/electron/assets/icons/logo-round.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
desktop/electron/assets/icons/logo-text.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
desktop/electron/assets/icons/logo-white.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
desktop/electron/assets/icons/logo.icns
Normal file
BIN
desktop/electron/assets/icons/logo.ico
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
desktop/electron/assets/icons/logo.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
1
desktop/electron/assets/icons/logo.svg
Normal file
After Width: | Height: | Size: 16 KiB |
32
desktop/electron/electron-builder.yml
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
appId: re.workadventu.desktop
|
||||||
|
|
||||||
|
files:
|
||||||
|
- "dist/**/*"
|
||||||
|
- "assets/**/*"
|
||||||
|
- from: "../local-app/dist/"
|
||||||
|
to: "local-app/dist"
|
||||||
|
|
||||||
|
directories:
|
||||||
|
output: ./build
|
||||||
|
|
||||||
|
dmg:
|
||||||
|
icon: false
|
||||||
|
|
||||||
|
linux:
|
||||||
|
category: "TODO;TODO"
|
||||||
|
packageCategory: "TODO;TODO"
|
||||||
|
icon: "assets/icons/logo.icns"
|
||||||
|
target:
|
||||||
|
- AppImage
|
||||||
|
artifactName: "${productName}-${version}-${arch}.${ext}"
|
||||||
|
|
||||||
|
win:
|
||||||
|
icon: "assets/icons/logo.ico"
|
||||||
|
artifactName: "${productName}-${version}-setup.${ext}"
|
||||||
|
|
||||||
|
publish:
|
||||||
|
provider: github
|
||||||
|
owner: thecodingmachine
|
||||||
|
repo: workadventure
|
||||||
|
vPrefixedTagName: false
|
||||||
|
releaseType: draft
|
44
desktop/electron/package.json
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"name": "workadventure-desktop",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Desktop application for WorkAdventure",
|
||||||
|
"author": "thecodingmachine",
|
||||||
|
"main": "dist/main.js",
|
||||||
|
"license": "SEE LICENSE IN LICENSE.txt",
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsup-node ./src/main.ts ./src/preload-local-app/preload.ts ./src/preload-app/preload.ts",
|
||||||
|
"build:local-app": "cd ../local-app && yarn && yarn build",
|
||||||
|
"dev": "yarn build --watch --onSuccess 'yarn electron dist/main.js'",
|
||||||
|
"dev:local-app": "cd ../local-app && yarn && yarn dev",
|
||||||
|
"bundle": "yarn build:local-app && yarn build && electron-builder install-app-deps && electron-builder",
|
||||||
|
"release": "yarn bundle",
|
||||||
|
"typecheck": "tsc --noEmit",
|
||||||
|
"test": "exit 0",
|
||||||
|
"lint": "yarn eslint src/ . --ext .ts",
|
||||||
|
"fix": "yarn eslint --fix src/ . --ext .ts",
|
||||||
|
"pretty": "yarn prettier --write 'src/**/*.{ts,tsx}'",
|
||||||
|
"pretty-check": "yarn prettier --check 'src/**/*.{ts,tsx}'"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"auto-launch": "^5.0.5",
|
||||||
|
"electron-is-dev": "^2.0.0",
|
||||||
|
"electron-log": "^4.4.6",
|
||||||
|
"electron-serve": "^1.1.0",
|
||||||
|
"electron-settings": "^4.0.2",
|
||||||
|
"electron-updater": "^4.6.5",
|
||||||
|
"electron-util": "^0.17.2",
|
||||||
|
"electron-window-state": "^5.0.3",
|
||||||
|
"node-fetch": "^3.2.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/auto-launch": "^5.0.2",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^2.26.0",
|
||||||
|
"@typescript-eslint/parser": "^2.26.0",
|
||||||
|
"electron": "^17.0.1",
|
||||||
|
"electron-builder": "^22.14.13",
|
||||||
|
"eslint": "^6.8.0",
|
||||||
|
"prettier": "^2.5.1",
|
||||||
|
"tsup": "^5.11.13",
|
||||||
|
"typescript": "^3.8.3"
|
||||||
|
}
|
||||||
|
}
|
90
desktop/electron/src/app.ts
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
import { app, BrowserWindow, globalShortcut } from "electron";
|
||||||
|
|
||||||
|
import { createWindow, getWindow } from "./window";
|
||||||
|
import { createTray } from "./tray";
|
||||||
|
import autoUpdater from "./auto-updater";
|
||||||
|
import { updateAutoLaunch } from "./auto-launch";
|
||||||
|
import ipc from "./ipc";
|
||||||
|
import settings from "./settings";
|
||||||
|
import { setLogLevel } from "./log";
|
||||||
|
import "./serve"; // prepare custom url scheme
|
||||||
|
import { loadShortcuts } from "./shortcuts";
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
const appLock = app.requestSingleInstanceLock();
|
||||||
|
|
||||||
|
if (!appLock) {
|
||||||
|
console.log("Application already running");
|
||||||
|
app.quit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
app.on("second-instance", () => {
|
||||||
|
// re-create window if closed
|
||||||
|
createWindow();
|
||||||
|
|
||||||
|
const mainWindow = getWindow();
|
||||||
|
|
||||||
|
// Someone tried to run a second instance, we should focus our window.
|
||||||
|
if (mainWindow) {
|
||||||
|
if (mainWindow.isMinimized()) {
|
||||||
|
mainWindow.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
mainWindow.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// This method will be called when Electron has finished loading
|
||||||
|
app.whenReady().then(async () => {
|
||||||
|
await settings.init();
|
||||||
|
|
||||||
|
setLogLevel(settings.get("log_level") || "info");
|
||||||
|
|
||||||
|
autoUpdater.init();
|
||||||
|
|
||||||
|
// enable auto launch
|
||||||
|
updateAutoLaunch();
|
||||||
|
|
||||||
|
// load ipc handler
|
||||||
|
ipc();
|
||||||
|
|
||||||
|
// Don't show the app in the doc
|
||||||
|
// if (app.dock) {
|
||||||
|
// app.dock.hide();
|
||||||
|
// }
|
||||||
|
|
||||||
|
await createWindow();
|
||||||
|
createTray();
|
||||||
|
|
||||||
|
loadShortcuts();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Quit when all windows are closed.
|
||||||
|
app.on("window-all-closed", () => {
|
||||||
|
// macOs users have to press Cmd + Q to stop the app
|
||||||
|
if (process.platform !== "darwin") {
|
||||||
|
app.quit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.on("activate", () => {
|
||||||
|
// On macOS it's common to re-create a window in the app when the
|
||||||
|
// dock icon is clicked and there are no other windows open.
|
||||||
|
if (BrowserWindow.getAllWindows().length === 0) {
|
||||||
|
createWindow();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.on("quit", () => {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
|
app.on("will-quit", () => {
|
||||||
|
globalShortcut.unregisterAll();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
init,
|
||||||
|
};
|
35
desktop/electron/src/auto-launch.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import AutoLaunch from "auto-launch";
|
||||||
|
import { app } from "electron";
|
||||||
|
import electronIsDev from "electron-is-dev";
|
||||||
|
|
||||||
|
import settings from "./settings";
|
||||||
|
|
||||||
|
export async function updateAutoLaunch() {
|
||||||
|
const isAutoLaunchEnabled = settings.get("auto_launch_enabled");
|
||||||
|
|
||||||
|
// Don't run this in development
|
||||||
|
if (electronIsDev) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// `setLoginItemSettings` doesn't support linux
|
||||||
|
if (process.platform === "linux") {
|
||||||
|
const autoLauncher = new AutoLaunch({
|
||||||
|
name: "WorkAdventure",
|
||||||
|
isHidden: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isAutoLaunchEnabled) {
|
||||||
|
await autoLauncher.enable();
|
||||||
|
} else {
|
||||||
|
await autoLauncher.disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
app.setLoginItemSettings({
|
||||||
|
openAtLogin: isAutoLaunchEnabled,
|
||||||
|
openAsHidden: true,
|
||||||
|
});
|
||||||
|
}
|
96
desktop/electron/src/auto-updater.ts
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
import { app, dialog } from "electron";
|
||||||
|
import { autoUpdater } from "electron-updater";
|
||||||
|
import log from "electron-log";
|
||||||
|
import * as isDev from "electron-is-dev";
|
||||||
|
import * as util from "util";
|
||||||
|
|
||||||
|
import { createAndShowNotification } from "./notification";
|
||||||
|
|
||||||
|
const sleep = util.promisify(setTimeout);
|
||||||
|
|
||||||
|
let isCheckPending = false;
|
||||||
|
let isManualRequestedUpdate = false;
|
||||||
|
|
||||||
|
export async function checkForUpdates() {
|
||||||
|
if (isCheckPending) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't do auto-updates in development
|
||||||
|
if (isDev) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for updates right away
|
||||||
|
await autoUpdater.checkForUpdates();
|
||||||
|
|
||||||
|
isCheckPending = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function manualRequestUpdateCheck() {
|
||||||
|
isManualRequestedUpdate = true;
|
||||||
|
|
||||||
|
createAndShowNotification({
|
||||||
|
body: "Checking for updates ...",
|
||||||
|
});
|
||||||
|
|
||||||
|
await checkForUpdates();
|
||||||
|
isManualRequestedUpdate = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
autoUpdater.logger = log;
|
||||||
|
|
||||||
|
autoUpdater.on("update-downloaded", ({ releaseNotes, releaseName }) => {
|
||||||
|
(async () => {
|
||||||
|
const dialogOpts = {
|
||||||
|
type: "question",
|
||||||
|
buttons: ["Install and Restart", "Install Later"],
|
||||||
|
defaultId: 0,
|
||||||
|
title: "WorkAdventure - Update",
|
||||||
|
message: process.platform === "win32" ? releaseNotes : releaseName,
|
||||||
|
detail: "A new version has been downloaded. Restart the application to apply the updates.",
|
||||||
|
};
|
||||||
|
|
||||||
|
const { response } = await dialog.showMessageBox(dialogOpts);
|
||||||
|
if (response === 0) {
|
||||||
|
await sleep(1000);
|
||||||
|
|
||||||
|
autoUpdater.quitAndInstall();
|
||||||
|
|
||||||
|
// Force app to quit. This is just a workaround, ideally autoUpdater.quitAndInstall() should relaunch the app.
|
||||||
|
// app.confirmedExitPrompt = true;
|
||||||
|
app.quit();
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (process.platform === "linux" && !process.env.APPIMAGE) {
|
||||||
|
autoUpdater.autoDownload = false;
|
||||||
|
autoUpdater.autoInstallOnAppQuit = false;
|
||||||
|
|
||||||
|
autoUpdater.on("update-available", () => {
|
||||||
|
createAndShowNotification({
|
||||||
|
title: "WorkAdventure - Update available",
|
||||||
|
body: "Please go to our website and install the newest version",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
autoUpdater.on("update-not-available", () => {
|
||||||
|
if (isManualRequestedUpdate) {
|
||||||
|
createAndShowNotification({
|
||||||
|
body: "No update available.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
checkForUpdates();
|
||||||
|
|
||||||
|
// run update check every hour again
|
||||||
|
setInterval(() => checkForUpdates, 1000 * 60 * 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
init,
|
||||||
|
};
|
98
desktop/electron/src/ipc.ts
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
import { ipcMain, app } from "electron";
|
||||||
|
import electronIsDev from "electron-is-dev";
|
||||||
|
import { createAndShowNotification } from "./notification";
|
||||||
|
import { Server } from "./preload-local-app/types";
|
||||||
|
import settings, { SettingsData } from "./settings";
|
||||||
|
import { loadShortcuts, setShortcutsEnabled } from "./shortcuts";
|
||||||
|
import { getAppView, hideAppView, showAppView } from "./window";
|
||||||
|
// import fetch from "node-fetch";
|
||||||
|
|
||||||
|
export function emitMuteToggle() {
|
||||||
|
const appView = getAppView();
|
||||||
|
if (!appView) {
|
||||||
|
throw new Error("Main window not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
appView.webContents.send("app:on-mute-toggle");
|
||||||
|
}
|
||||||
|
|
||||||
|
export function emitCameraToggle() {
|
||||||
|
const appView = getAppView();
|
||||||
|
if (!appView) {
|
||||||
|
throw new Error("Main window not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
appView.webContents.send("app:on-camera-toggle");
|
||||||
|
}
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
ipcMain.handle("is-development", () => electronIsDev);
|
||||||
|
ipcMain.handle("get-version", () => (electronIsDev ? "dev" : app.getVersion()));
|
||||||
|
|
||||||
|
// app ipc
|
||||||
|
ipcMain.on("app:notify", (event, txt) => {
|
||||||
|
createAndShowNotification({ body: txt });
|
||||||
|
});
|
||||||
|
|
||||||
|
// local-app ipc
|
||||||
|
ipcMain.handle("local-app:showLocalApp", () => {
|
||||||
|
hideAppView();
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcMain.handle("local-app:getServers", () => {
|
||||||
|
return settings.get("servers");
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcMain.handle("local-app:selectServer", (event, serverId: string) => {
|
||||||
|
const servers = settings.get("servers") || [];
|
||||||
|
const selectedServer = servers.find((s) => s._id === serverId);
|
||||||
|
|
||||||
|
if (!selectedServer) {
|
||||||
|
return new Error("Server not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
showAppView(selectedServer.url);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcMain.handle("local-app:addServer", (event, server: Omit<Server, "_id">) => {
|
||||||
|
const servers = settings.get("servers") || [];
|
||||||
|
|
||||||
|
// TODO: add proper test to see if server url is valid and points to a real WA server
|
||||||
|
// try {
|
||||||
|
//
|
||||||
|
// await fetch(`${server.url}/iframe_api.js`);
|
||||||
|
// } catch (e) {
|
||||||
|
// console.error(e);
|
||||||
|
// return new Error("Invalid server url");
|
||||||
|
// }
|
||||||
|
|
||||||
|
const newServer = {
|
||||||
|
...server,
|
||||||
|
_id: `${Date.now()}-${servers.length + 1}`,
|
||||||
|
};
|
||||||
|
servers.push(newServer);
|
||||||
|
settings.set("servers", servers);
|
||||||
|
return newServer;
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcMain.handle("local-app:removeServer", (event, server: Server) => {
|
||||||
|
const servers = settings.get("servers") || [];
|
||||||
|
settings.set(
|
||||||
|
"servers",
|
||||||
|
servers.filter((s) => s._id !== server._id)
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcMain.handle("local-app:reloadShortcuts", (event) => loadShortcuts());
|
||||||
|
|
||||||
|
ipcMain.handle("local-app:getSettings", (event) => settings.get() || {});
|
||||||
|
ipcMain.handle(
|
||||||
|
"local-app:saveSetting",
|
||||||
|
<T extends keyof SettingsData>(event: Electron.IpcMainInvokeEvent, key: T, value: SettingsData[T]) =>
|
||||||
|
settings.set(key, value)
|
||||||
|
);
|
||||||
|
|
||||||
|
ipcMain.handle("local-app:setShortcutsEnabled", (event, enabled: boolean) => setShortcutsEnabled(enabled));
|
||||||
|
};
|
54
desktop/electron/src/log.ts
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import { dialog, shell } from "electron";
|
||||||
|
import ElectronLog from "electron-log";
|
||||||
|
import log from "electron-log";
|
||||||
|
|
||||||
|
function onError(e: Error) {
|
||||||
|
try {
|
||||||
|
log.error(e);
|
||||||
|
|
||||||
|
dialog.showErrorBox("WorkAdventure - A JavaScript error occurred", e.stack || "");
|
||||||
|
} catch (logError) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onRejection(reason: Error) {
|
||||||
|
if (reason instanceof Error) {
|
||||||
|
let _reason = reason;
|
||||||
|
const errPrototype = Object.getPrototypeOf(reason);
|
||||||
|
const nameProperty = Object.getOwnPropertyDescriptor(errPrototype, "name");
|
||||||
|
|
||||||
|
if (!nameProperty || !nameProperty.writable) {
|
||||||
|
_reason = new Error(reason.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
_reason.name = `UnhandledRejection ${_reason.name}`;
|
||||||
|
onError(_reason);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const error = new Error(JSON.stringify(reason));
|
||||||
|
error.name = "UnhandledRejection";
|
||||||
|
onError(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
console.log = log.log.bind(log);
|
||||||
|
|
||||||
|
process.on("uncaughtException", onError);
|
||||||
|
process.on("unhandledRejection", onRejection);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function openLog() {
|
||||||
|
const logFilePath = log.transports.file.getFile().path;
|
||||||
|
await shell.openPath(logFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setLogLevel(logLevel: ElectronLog.LogLevel) {
|
||||||
|
log.transports.console.level = logLevel;
|
||||||
|
log.transports.file.level = logLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
init,
|
||||||
|
};
|
5
desktop/electron/src/main.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import app from "./app";
|
||||||
|
import log from "./log";
|
||||||
|
|
||||||
|
log.init();
|
||||||
|
app.init();
|
20
desktop/electron/src/notification.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import path from "path";
|
||||||
|
import { Notification, NotificationConstructorOptions } from "electron";
|
||||||
|
|
||||||
|
export function createNotification(options: Partial<NotificationConstructorOptions>) {
|
||||||
|
const notification = new Notification({
|
||||||
|
title: "WorkAdventure",
|
||||||
|
icon: path.join(__dirname, "..", "assets", "icons", "logo.png"),
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
|
||||||
|
return notification;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createAndShowNotification(options: Partial<NotificationConstructorOptions>) {
|
||||||
|
const notification = createNotification(options);
|
||||||
|
|
||||||
|
notification.show();
|
||||||
|
|
||||||
|
return notification;
|
||||||
|
}
|
13
desktop/electron/src/preload-app/preload.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { contextBridge, ipcRenderer } from "electron";
|
||||||
|
import type { WorkAdventureDesktopApi } from "./types";
|
||||||
|
|
||||||
|
const api: WorkAdventureDesktopApi = {
|
||||||
|
desktop: true,
|
||||||
|
isDevelopment: () => ipcRenderer.invoke("is-development"),
|
||||||
|
getVersion: () => ipcRenderer.invoke("get-version"),
|
||||||
|
notify: (txt) => ipcRenderer.send("app:notify", txt),
|
||||||
|
onMuteToggle: (callback) => ipcRenderer.on("app:on-mute-toggle", callback),
|
||||||
|
onCameraToggle: (callback) => ipcRenderer.on("app:on-camera-toggle", callback),
|
||||||
|
};
|
||||||
|
|
||||||
|
contextBridge.exposeInMainWorld("WAD", api);
|
8
desktop/electron/src/preload-app/types.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
export type WorkAdventureDesktopApi = {
|
||||||
|
desktop: boolean;
|
||||||
|
isDevelopment: () => Promise<boolean>;
|
||||||
|
getVersion: () => Promise<string>;
|
||||||
|
notify: (txt: string) => void;
|
||||||
|
onMuteToggle: (callback: () => void) => void;
|
||||||
|
onCameraToggle: (callback: () => void) => void;
|
||||||
|
};
|
19
desktop/electron/src/preload-local-app/preload.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { contextBridge, ipcRenderer } from "electron";
|
||||||
|
import type { WorkAdventureLocalAppApi } from "./types";
|
||||||
|
|
||||||
|
const api: WorkAdventureLocalAppApi = {
|
||||||
|
desktop: true,
|
||||||
|
isDevelopment: () => ipcRenderer.invoke("is-development"),
|
||||||
|
getVersion: () => ipcRenderer.invoke("get-version"),
|
||||||
|
showLocalApp: () => ipcRenderer.invoke("local-app:showLocalApp"),
|
||||||
|
getServers: () => ipcRenderer.invoke("local-app:getServers"),
|
||||||
|
selectServer: (serverId) => ipcRenderer.invoke("local-app:selectServer", serverId),
|
||||||
|
addServer: (server) => ipcRenderer.invoke("local-app:addServer", server),
|
||||||
|
removeServer: (serverId) => ipcRenderer.invoke("local-app:removeServer", serverId),
|
||||||
|
reloadShortcuts: () => ipcRenderer.invoke("local-app:reloadShortcuts"),
|
||||||
|
getSettings: () => ipcRenderer.invoke("local-app:getSettings"),
|
||||||
|
saveSetting: (key, value) => ipcRenderer.invoke("local-app:saveSetting", key, value),
|
||||||
|
setShortcutsEnabled: (enabled) => ipcRenderer.invoke("local-app:setShortcutsEnabled", enabled),
|
||||||
|
};
|
||||||
|
|
||||||
|
contextBridge.exposeInMainWorld("WAD", api);
|
24
desktop/electron/src/preload-local-app/types.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { SettingsData } from "../settings";
|
||||||
|
|
||||||
|
export type Server = {
|
||||||
|
_id: string;
|
||||||
|
name: string;
|
||||||
|
url: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export { SettingsData };
|
||||||
|
|
||||||
|
export type WorkAdventureLocalAppApi = {
|
||||||
|
desktop: boolean;
|
||||||
|
isDevelopment: () => Promise<boolean>;
|
||||||
|
getVersion: () => Promise<string>;
|
||||||
|
showLocalApp: () => Promise<void>;
|
||||||
|
getServers: () => Promise<Server[]>;
|
||||||
|
selectServer: (serverId: string) => Promise<Error | boolean>;
|
||||||
|
addServer: (server: Omit<Server, "_id">) => Promise<Server | Error>;
|
||||||
|
removeServer: (serverId: Server["_id"]) => Promise<boolean>;
|
||||||
|
reloadShortcuts: () => Promise<void>;
|
||||||
|
getSettings: () => Promise<SettingsData>;
|
||||||
|
saveSetting: <T extends keyof SettingsData>(key: T, value: SettingsData[T]) => Promise<void>;
|
||||||
|
setShortcutsEnabled: (enabled: boolean) => Promise<void>;
|
||||||
|
};
|
9
desktop/electron/src/serve.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { BrowserWindow } from "electron";
|
||||||
|
import serve from "electron-serve";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
|
const customScheme = serve({ directory: path.resolve(__dirname, "..", "local-app", "dist") });
|
||||||
|
|
||||||
|
export async function loadCustomScheme(window: BrowserWindow) {
|
||||||
|
await customScheme(window);
|
||||||
|
}
|
72
desktop/electron/src/settings.ts
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import ElectronLog from "electron-log";
|
||||||
|
import Settings from "electron-settings";
|
||||||
|
import type { Server } from "./preload-local-app/types";
|
||||||
|
|
||||||
|
export type SettingsData = {
|
||||||
|
log_level: ElectronLog.LogLevel;
|
||||||
|
auto_launch_enabled: boolean;
|
||||||
|
servers: Server[];
|
||||||
|
shortcuts: Record<"mute_toggle" | "camera_toggle", string>;
|
||||||
|
};
|
||||||
|
|
||||||
|
let settings: SettingsData;
|
||||||
|
|
||||||
|
const defaultSettings: SettingsData = {
|
||||||
|
log_level: "info",
|
||||||
|
auto_launch_enabled: true,
|
||||||
|
servers: [
|
||||||
|
{
|
||||||
|
_id: `${Date.now()}-1`,
|
||||||
|
name: "WA Demo",
|
||||||
|
url: "https://play.staging.workadventu.re/@/tcm/workadventure/wa-village",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
shortcuts: {
|
||||||
|
mute_toggle: "",
|
||||||
|
camera_toggle: "",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
async function init() {
|
||||||
|
let _settings = await Settings.get();
|
||||||
|
if (Object.keys(_settings).length === 0) {
|
||||||
|
_settings = defaultSettings;
|
||||||
|
}
|
||||||
|
settings = _settings as SettingsData;
|
||||||
|
}
|
||||||
|
|
||||||
|
function get(): SettingsData;
|
||||||
|
function get<T extends keyof SettingsData>(key: T): SettingsData[T] | undefined;
|
||||||
|
function get<T extends keyof SettingsData>(key?: T): SettingsData | SettingsData[T] | undefined {
|
||||||
|
if (settings === undefined) {
|
||||||
|
throw new Error("Settings not initialized");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key === undefined) {
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
return settings?.[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
function set(key: SettingsData): void;
|
||||||
|
function set<T extends keyof SettingsData>(key: T, value: SettingsData[T]): void;
|
||||||
|
function set<T extends keyof SettingsData>(key: T | SettingsData, value?: SettingsData[T]) {
|
||||||
|
if (settings === undefined) {
|
||||||
|
throw new Error("Settings not initialized");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof key === "string" && value !== undefined) {
|
||||||
|
settings[key] = value;
|
||||||
|
} else if (typeof key !== "string") {
|
||||||
|
Object.assign(settings, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings.set(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
init,
|
||||||
|
get,
|
||||||
|
set,
|
||||||
|
};
|
36
desktop/electron/src/shortcuts.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { globalShortcut } from "electron";
|
||||||
|
import settings, { SettingsData } from "./settings";
|
||||||
|
import { emitCameraToggle, emitMuteToggle } from "./ipc";
|
||||||
|
|
||||||
|
export function setShortcutsEnabled(enabled: boolean) {
|
||||||
|
if (enabled) {
|
||||||
|
loadShortcuts();
|
||||||
|
} else {
|
||||||
|
globalShortcut.unregisterAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function loadShortcuts() {
|
||||||
|
globalShortcut.unregisterAll();
|
||||||
|
|
||||||
|
const shortcuts = settings.get("shortcuts");
|
||||||
|
|
||||||
|
if (shortcuts?.mute_toggle && shortcuts.mute_toggle.length > 0) {
|
||||||
|
globalShortcut.register(shortcuts.mute_toggle, () => {
|
||||||
|
emitMuteToggle();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shortcuts?.camera_toggle && shortcuts.camera_toggle.length > 0) {
|
||||||
|
globalShortcut.register(shortcuts.camera_toggle, () => {
|
||||||
|
emitCameraToggle();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function saveShortcut(shortcut: keyof SettingsData["shortcuts"], key: string) {
|
||||||
|
const shortcuts = settings.get("shortcuts") || <SettingsData["shortcuts"]>{};
|
||||||
|
shortcuts[shortcut] = key;
|
||||||
|
settings.set("shortcuts", shortcuts);
|
||||||
|
loadShortcuts();
|
||||||
|
}
|
84
desktop/electron/src/tray.ts
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import { app, Tray, Menu } from "electron";
|
||||||
|
import path from "path";
|
||||||
|
import { showAboutWindow } from "electron-util";
|
||||||
|
|
||||||
|
import * as autoUpdater from "./auto-updater";
|
||||||
|
import * as log from "./log";
|
||||||
|
import { getAppView, getWindow } from "./window";
|
||||||
|
|
||||||
|
let tray: Tray | undefined;
|
||||||
|
|
||||||
|
const assetsDirectory = path.join(__dirname, "..", "assets");
|
||||||
|
|
||||||
|
export function getTray() {
|
||||||
|
return tray;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createTray() {
|
||||||
|
tray = new Tray(path.join(assetsDirectory, "icons", "logo.png"));
|
||||||
|
|
||||||
|
const trayContextMenu = Menu.buildFromTemplate([
|
||||||
|
{
|
||||||
|
id: "open",
|
||||||
|
label: "Show / Hide",
|
||||||
|
click() {
|
||||||
|
const mainWindow = getWindow();
|
||||||
|
if (!mainWindow) {
|
||||||
|
throw new Error("Main window not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mainWindow.isVisible()) {
|
||||||
|
mainWindow.hide();
|
||||||
|
} else {
|
||||||
|
mainWindow.show();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Check for updates",
|
||||||
|
async click() {
|
||||||
|
await autoUpdater.manualRequestUpdateCheck();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Open Logs",
|
||||||
|
click() {
|
||||||
|
log.openLog();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Open DevTools",
|
||||||
|
click() {
|
||||||
|
getWindow()?.webContents.openDevTools({ mode: "detach" });
|
||||||
|
getAppView()?.webContents.openDevTools({ mode: "detach" });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "About",
|
||||||
|
click() {
|
||||||
|
showAboutWindow({
|
||||||
|
icon: path.join(assetsDirectory, "icons", "logo.png"),
|
||||||
|
copyright: "Copyright © WorkAdventure",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Quit",
|
||||||
|
click() {
|
||||||
|
// app.confirmedExitPrompt = true;
|
||||||
|
app.quit();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
tray.setContextMenu(trayContextMenu);
|
||||||
|
|
||||||
|
tray.on("double-click", () => {
|
||||||
|
const mainWindow = getWindow();
|
||||||
|
if (!mainWindow) {
|
||||||
|
throw new Error("Main window not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
mainWindow.show();
|
||||||
|
});
|
||||||
|
}
|
150
desktop/electron/src/window.ts
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
import { BrowserView, BrowserWindow, app } from "electron";
|
||||||
|
import electronIsDev from "electron-is-dev";
|
||||||
|
import windowStateKeeper from "electron-window-state";
|
||||||
|
import path from "path";
|
||||||
|
import { loadCustomScheme } from "./serve";
|
||||||
|
|
||||||
|
let mainWindow: BrowserWindow | undefined;
|
||||||
|
let appView: BrowserView | undefined;
|
||||||
|
let appViewUrl = "";
|
||||||
|
|
||||||
|
const sidebarWidth = 80;
|
||||||
|
|
||||||
|
export function getWindow() {
|
||||||
|
return mainWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getAppView() {
|
||||||
|
return appView;
|
||||||
|
}
|
||||||
|
|
||||||
|
function resizeAppView() {
|
||||||
|
// TODO: workaround: set timeout is needed as mainWindow.getBounds() needs some time to update
|
||||||
|
setTimeout(() => {
|
||||||
|
if (!mainWindow || !appView) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { width, height } = mainWindow.getBounds();
|
||||||
|
|
||||||
|
appView.setBounds({
|
||||||
|
x: sidebarWidth,
|
||||||
|
y: 0,
|
||||||
|
width: width - sidebarWidth,
|
||||||
|
height: height,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createWindow() {
|
||||||
|
// do not re-create window if still existing
|
||||||
|
if (mainWindow) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the previous state with fallback to defaults
|
||||||
|
const windowState = windowStateKeeper({
|
||||||
|
defaultWidth: 1000,
|
||||||
|
defaultHeight: 800,
|
||||||
|
maximize: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
mainWindow = new BrowserWindow({
|
||||||
|
x: windowState.x,
|
||||||
|
y: windowState.y,
|
||||||
|
width: windowState.width,
|
||||||
|
height: windowState.height,
|
||||||
|
autoHideMenuBar: true,
|
||||||
|
show: false,
|
||||||
|
webPreferences: {
|
||||||
|
preload: path.resolve(__dirname, "..", "dist", "preload-local-app", "preload.js"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
mainWindow.setMenu(null);
|
||||||
|
|
||||||
|
// Let us register listeners on the window, so we can update the state
|
||||||
|
// automatically (the listeners will be removed when the window is closed)
|
||||||
|
// and restore the maximized or full screen state
|
||||||
|
windowState.manage(mainWindow);
|
||||||
|
|
||||||
|
mainWindow.on("closed", () => {
|
||||||
|
mainWindow = undefined;
|
||||||
|
});
|
||||||
|
|
||||||
|
// mainWindow.on('close', async (event) => {
|
||||||
|
// if (!app.confirmedExitPrompt) {
|
||||||
|
// event.preventDefault(); // Prevents the window from closing
|
||||||
|
// const choice = await dialog.showMessageBox(getMainWindow(), {
|
||||||
|
// type: 'question',
|
||||||
|
// buttons: ['Yes', 'Abort'],
|
||||||
|
// title: 'Confirm',
|
||||||
|
// message: 'Are you sure you want to quit?',
|
||||||
|
// });
|
||||||
|
// if (choice.response === 0) {
|
||||||
|
// app.confirmedExitPrompt = true;
|
||||||
|
// mainWindow.close();
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// app.confirmedExitPrompt = false;
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
appView = new BrowserView({
|
||||||
|
webPreferences: {
|
||||||
|
preload: path.resolve(__dirname, "..", "dist", "preload-app", "preload.js"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
resizeAppView();
|
||||||
|
appView.setAutoResize({ width: true, height: true });
|
||||||
|
mainWindow.on("resize", resizeAppView);
|
||||||
|
|
||||||
|
mainWindow.once("ready-to-show", () => {
|
||||||
|
mainWindow?.show();
|
||||||
|
});
|
||||||
|
|
||||||
|
mainWindow.webContents.on("did-finish-load", () => {
|
||||||
|
mainWindow?.setTitle("WorkAdventure Desktop (alpha release)");
|
||||||
|
});
|
||||||
|
|
||||||
|
if (electronIsDev && process.env.LOCAL_APP_URL) {
|
||||||
|
await mainWindow.loadURL(process.env.LOCAL_APP_URL);
|
||||||
|
} else {
|
||||||
|
// load custom url scheme app://
|
||||||
|
await loadCustomScheme(mainWindow);
|
||||||
|
await mainWindow.loadURL("app://-");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function showAppView(url?: string) {
|
||||||
|
if (!appView) {
|
||||||
|
throw new Error("App view not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mainWindow) {
|
||||||
|
throw new Error("Main window not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mainWindow.getBrowserView()) {
|
||||||
|
mainWindow.removeBrowserView(appView);
|
||||||
|
}
|
||||||
|
mainWindow.addBrowserView(appView);
|
||||||
|
|
||||||
|
if (url && url !== appViewUrl) {
|
||||||
|
appView.webContents.loadURL(url);
|
||||||
|
appViewUrl = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
appView.webContents.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function hideAppView() {
|
||||||
|
if (!appView) {
|
||||||
|
throw new Error("App view not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mainWindow) {
|
||||||
|
throw new Error("Main window not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
mainWindow.removeBrowserView(appView);
|
||||||
|
}
|
0
desktop/electron/tests/.gitkeep
Normal file
21
desktop/electron/tsconfig.json
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"target": "es5",
|
||||||
|
"downlevelIteration": true,
|
||||||
|
"module": "commonjs",
|
||||||
|
"allowJs": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"outDir": "./dist",
|
||||||
|
"strict": true,
|
||||||
|
"noImplicitThis": false,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {},
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"skipLibCheck": true
|
||||||
|
}
|
||||||
|
}
|
3243
desktop/electron/yarn.lock
Normal file
24
desktop/local-app/.gitignore
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
1
desktop/local-app/.prettierignore
Normal file
@ -0,0 +1 @@
|
|||||||
|
src/Messages/generated
|
4
desktop/local-app/.prettierrc.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"printWidth": 120,
|
||||||
|
"tabWidth": 4
|
||||||
|
}
|
48
desktop/local-app/index.html
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<meta http-equiv="Content-Security-Policy" content="script-src 'self';" />
|
||||||
|
<title>WorkAdventure Desktop</title>
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body,
|
||||||
|
#app {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
*::-webkit-scrollbar {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
}
|
||||||
|
*::-webkit-scrollbar-track {
|
||||||
|
background-color: transparent;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
*::-webkit-scrollbar-thumb {
|
||||||
|
background-color: rgba(0, 0, 0, 0.4);
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.ts"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
36
desktop/local-app/package.json
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"name": "vite-project",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vite build",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"check": "svelte-check --tsconfig ./tsconfig.json",
|
||||||
|
"lint": "exit 0",
|
||||||
|
"test": "exit 0",
|
||||||
|
"pretty": "yarn prettier --write 'src/**/*.{ts,tsx,svelte}'",
|
||||||
|
"pretty-check": "yarn prettier --check 'src/**/*.{ts,tsx}'"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@sveltejs/vite-plugin-svelte": "^1.0.0-next.30",
|
||||||
|
"@tsconfig/svelte": "^2.0.1",
|
||||||
|
"prettier": "^2.5.1",
|
||||||
|
"prettier-plugin-svelte": "^2.6.0",
|
||||||
|
"rollup-plugin-svelte-svg": "^1.0.0-beta.6",
|
||||||
|
"svelte": "^3.44.0",
|
||||||
|
"svelte-check": "^2.2.7",
|
||||||
|
"svelte-navigator": "^3.1.5",
|
||||||
|
"svelte-preprocess": "^4.9.8",
|
||||||
|
"tslib": "^2.3.1",
|
||||||
|
"typescript": "^4.5.4",
|
||||||
|
"vite": "^2.8.0",
|
||||||
|
"vite-plugin-windicss": "^1.7.1",
|
||||||
|
"windicss": "^3.4.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@16bits/nes.css": "^2.3.2",
|
||||||
|
"@fontsource/press-start-2p": "^4.5.2"
|
||||||
|
}
|
||||||
|
}
|
46
desktop/local-app/src/App.svelte
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { Router, Route } from "svelte-navigator";
|
||||||
|
|
||||||
|
import Sidebar from "~/lib/Sidebar.svelte";
|
||||||
|
import LazyRoute from "~/lib/LazyRoute.svelte";
|
||||||
|
import { api } from "~/lib/ipc";
|
||||||
|
|
||||||
|
const Home = () => import("~/views/Home.svelte");
|
||||||
|
const AddServer = () => import("~/views/AddServer.svelte");
|
||||||
|
const Settings = () => import("~/views/Settings.svelte");
|
||||||
|
const Server = () => import("~/views/Server.svelte");
|
||||||
|
|
||||||
|
let insideElectron = api?.desktop;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if insideElectron}
|
||||||
|
<Router>
|
||||||
|
<Sidebar />
|
||||||
|
<main class="flex flex-grow">
|
||||||
|
<LazyRoute path="/" component={Home} delayMs={500}>Loading ...</LazyRoute>
|
||||||
|
<LazyRoute path="/server/add" component={AddServer} delayMs={500}>Loading ...</LazyRoute>
|
||||||
|
<LazyRoute path="/settings" component={Settings} delayMs={500}>Loading ...</LazyRoute>
|
||||||
|
<LazyRoute path="/server/:id" component={Server} delayMs={500}>Loading ...</LazyRoute>
|
||||||
|
<Route>
|
||||||
|
<h3>404</h3>
|
||||||
|
<p>No Route could be matched.</p>
|
||||||
|
</Route>
|
||||||
|
</main>
|
||||||
|
</Router>
|
||||||
|
{:else}
|
||||||
|
<main class="flex flex-grow justify-center items-center">Please open the app inside of Electron.</main>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
@import "@fontsource/press-start-2p/index.css";
|
||||||
|
@import "@16bits/nes.css/css/nes.min.css";
|
||||||
|
|
||||||
|
:root {
|
||||||
|
font-family: "Press Start 2P", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell,
|
||||||
|
"Open Sans", "Helvetica Neue", sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
background-color: #30343d;
|
||||||
|
}
|
||||||
|
</style>
|
3
desktop/local-app/src/assets/nes.icons/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# NES.icons
|
||||||
|
|
||||||
|
Source: https://github.com/nostalgic-css/NES.icons/
|
103
desktop/local-app/src/assets/nes.icons/cog.svg
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="7" y="0" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="8" y="0" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="2" y="1" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="7" y="1" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="8" y="1" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="13" y="1" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="1" y="2" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="2" y="2" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="3" y="2" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="5" y="2" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="6" y="2" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="7" y="2" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="8" y="2" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="9" y="2" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="10" y="2" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="12" y="2" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="13" y="2" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="14" y="2" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="2" y="3" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="3" y="3" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="4" y="3" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="5" y="3" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="6" y="3" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="7" y="3" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="8" y="3" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="9" y="3" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="10" y="3" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="11" y="3" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="12" y="3" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="13" y="3" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="3" y="4" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="4" y="4" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="11" y="4" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="12" y="4" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="2" y="5" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="3" y="5" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="12" y="5" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="13" y="5" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="2" y="6" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="3" y="6" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="12" y="6" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="13" y="6" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="0" y="7" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="1" y="7" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="2" y="7" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="3" y="7" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="12" y="7" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="13" y="7" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="14" y="7" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="15" y="7" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="0" y="8" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="1" y="8" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="2" y="8" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="3" y="8" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="12" y="8" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="13" y="8" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="14" y="8" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="15" y="8" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="2" y="9" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="3" y="9" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="12" y="9" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="13" y="9" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="2" y="10" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="3" y="10" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="12" y="10" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="13" y="10" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="3" y="11" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="4" y="11" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="11" y="11" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="12" y="11" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="2" y="12" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="3" y="12" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="4" y="12" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="5" y="12" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="6" y="12" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="7" y="12" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="8" y="12" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="9" y="12" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="10" y="12" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="11" y="12" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="12" y="12" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="13" y="12" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="1" y="13" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="2" y="13" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="3" y="13" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="5" y="13" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="6" y="13" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="7" y="13" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="8" y="13" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="9" y="13" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="10" y="13" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="12" y="13" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="13" y="13" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="14" y="13" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="2" y="14" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="7" y="14" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="8" y="14" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="13" y="14" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="7" y="15" width="1" height="1" fill="#000000" />
|
||||||
|
<rect x="8" y="15" width="1" height="1" fill="#000000" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 5.8 KiB |
15
desktop/local-app/src/lib/InputField.svelte
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export let title: string;
|
||||||
|
export let id: string;
|
||||||
|
export let description: string = "";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="mb-6">
|
||||||
|
<label class="block text-gray-200 text-lg font-bold mb-1" for={id}>
|
||||||
|
{title}
|
||||||
|
</label>
|
||||||
|
<slot />
|
||||||
|
{#if description.length > 0}
|
||||||
|
<p class="text-gray-200 text-xs mt-1 italic">{description}</p>
|
||||||
|
{/if}
|
||||||
|
</div>
|
179
desktop/local-app/src/lib/KeyRecord.svelte
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { createEventDispatcher } from "svelte";
|
||||||
|
|
||||||
|
export let id: string;
|
||||||
|
export let value: string = "";
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher<{
|
||||||
|
change: string;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
// https://www.electronjs.org/de/docs/latest/api/accelerator
|
||||||
|
function keyCodeToElectron(key: string): string {
|
||||||
|
if (key.match(/^Key[A-Z]/)) {
|
||||||
|
return key.replace(/^Key/, "").toLocaleUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key.match(/^Digit[0-9]/)) {
|
||||||
|
return key.replace(/^Digit/, "").toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key.match(/^Numpad[0-9]/)) {
|
||||||
|
return key.replace(/^Numpad/, "num").toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (key) {
|
||||||
|
// Modifiers
|
||||||
|
case "ControlLeft":
|
||||||
|
return "CmdOrCtrl";
|
||||||
|
case "ControlRight":
|
||||||
|
return "CmdOrCtrl";
|
||||||
|
case "AltLeft":
|
||||||
|
return "Alt";
|
||||||
|
case "AltRight":
|
||||||
|
return "AltGr";
|
||||||
|
case "ScrollLock":
|
||||||
|
return "Scrolllock";
|
||||||
|
case "ShiftLeft":
|
||||||
|
return "Shift";
|
||||||
|
case "ShiftRight":
|
||||||
|
return "Shift";
|
||||||
|
// Specialchars
|
||||||
|
case "Period":
|
||||||
|
return ".";
|
||||||
|
case "Comma":
|
||||||
|
return ",";
|
||||||
|
case "Slash":
|
||||||
|
return "/";
|
||||||
|
case "Backslash":
|
||||||
|
return "\\";
|
||||||
|
case "Minus":
|
||||||
|
return "-";
|
||||||
|
case "Equal":
|
||||||
|
return "=";
|
||||||
|
case "BracketLeft":
|
||||||
|
return "[";
|
||||||
|
case "BracketRight":
|
||||||
|
return "]";
|
||||||
|
case "Quote":
|
||||||
|
return "'";
|
||||||
|
case "Semicolon":
|
||||||
|
return ";";
|
||||||
|
case "IntlBackslash":
|
||||||
|
return "\\";
|
||||||
|
case "Backquote":
|
||||||
|
return "`";
|
||||||
|
// Numpad
|
||||||
|
case "NumpadDecimal":
|
||||||
|
return "numdec";
|
||||||
|
case "NumpadAdd":
|
||||||
|
return "numadd";
|
||||||
|
case "NumpadSubtract":
|
||||||
|
return "numsub";
|
||||||
|
case "NumpadMultiply":
|
||||||
|
return "nummult";
|
||||||
|
case "NumpadDivide":
|
||||||
|
return "numdiv";
|
||||||
|
default:
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let shortCut: string[] = [];
|
||||||
|
let recording = false;
|
||||||
|
let recordingTimeout: NodeJS.Timeout;
|
||||||
|
let keyInputTimeout: NodeJS.Timeout;
|
||||||
|
|
||||||
|
function camelPad(str: string) {
|
||||||
|
return (
|
||||||
|
str
|
||||||
|
// Look for long acronyms and filter out the last letter
|
||||||
|
.replace(/([A-Z]+)([A-Z][a-z])/g, " $1 $2")
|
||||||
|
// Look for lower-case letters followed by upper-case letters
|
||||||
|
.replace(/([a-z\d])([A-Z])/g, "$1 $2")
|
||||||
|
// Look for lower-case letters followed by numbers
|
||||||
|
// .replace(/([a-zA-Z])(\d)/g, "$1 $2")
|
||||||
|
.replace(/^./, (str) => str.toUpperCase())
|
||||||
|
// Remove any white space left around the word
|
||||||
|
.trim()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetRecording() {
|
||||||
|
recording = false;
|
||||||
|
shortCut = [];
|
||||||
|
value = "";
|
||||||
|
dispatch("change", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopRecording() {
|
||||||
|
clearTimeout(recordingTimeout);
|
||||||
|
recording = false;
|
||||||
|
value = shortCut.map(keyCodeToElectron).join(" + ");
|
||||||
|
dispatch("change", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function startRecording() {
|
||||||
|
if (recording) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
recording = true;
|
||||||
|
value = "";
|
||||||
|
shortCut = [];
|
||||||
|
|
||||||
|
recordingTimeout = setTimeout(() => {
|
||||||
|
stopRecording();
|
||||||
|
}, 1000 * 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
function keyUp(event: KeyboardEvent) {
|
||||||
|
if (!recording) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
shortCut = [...shortCut, event.code];
|
||||||
|
|
||||||
|
if (!keyInputTimeout) {
|
||||||
|
keyInputTimeout = setTimeout(() => {
|
||||||
|
stopRecording();
|
||||||
|
keyInputTimeout = undefined;
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class={`flex items-center w-full h-8 border-1 rounded-md overflow-hidden text-gray-200 text-xs appearance-none focus:outline-none ${
|
||||||
|
recording ? "border-red-500" : "border-gray-400"
|
||||||
|
}`}
|
||||||
|
on:keyup={keyUp}
|
||||||
|
on:click={startRecording}
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
{id}
|
||||||
|
type="text"
|
||||||
|
class="flex-grow h-full border-none mx-2 bg-transparent appearance-none focus:outline-none"
|
||||||
|
disabled
|
||||||
|
{value}
|
||||||
|
/>
|
||||||
|
{#if value.length > 0}
|
||||||
|
<span
|
||||||
|
class="flex items-center justify-center w-4 h-4 p-2 mr-1 rounded-full cursor-pointer bg-gray-500 hover:bg-gray-400"
|
||||||
|
on:click|stopPropagation={resetRecording}>x</span
|
||||||
|
>
|
||||||
|
{/if}
|
||||||
|
<div
|
||||||
|
class={`flex h-6 items-center px-2 m-0.5 rounded-sm w-28 justify-center cursor-pointer ${
|
||||||
|
recording ? "bg-red-500" : "hover:bg-gray-400"
|
||||||
|
}`}
|
||||||
|
on:click={recording ? stopRecording : startRecording}
|
||||||
|
>
|
||||||
|
{#if recording}
|
||||||
|
<span>recording</span>
|
||||||
|
{:else}
|
||||||
|
<span>record</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
35
desktop/local-app/src/lib/Lazy.svelte
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<script>
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
|
||||||
|
export let component;
|
||||||
|
export let delayMs = null;
|
||||||
|
|
||||||
|
let loadedComponent = null;
|
||||||
|
let timeout;
|
||||||
|
let showFallback = !delayMs;
|
||||||
|
|
||||||
|
let props;
|
||||||
|
$: {
|
||||||
|
// eslint-disable-next-line no-shadow
|
||||||
|
const { component, delayMs, ...restProps } = $$props;
|
||||||
|
props = restProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
if (delayMs) {
|
||||||
|
timeout = setTimeout(() => {
|
||||||
|
showFallback = true;
|
||||||
|
}, delayMs);
|
||||||
|
}
|
||||||
|
component().then((module) => {
|
||||||
|
loadedComponent = module.default;
|
||||||
|
});
|
||||||
|
return () => clearTimeout(timeout);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if loadedComponent}
|
||||||
|
<svelte:component this={loadedComponent} {...props} />
|
||||||
|
{:else if showFallback}
|
||||||
|
<slot />
|
||||||
|
{/if}
|
20
desktop/local-app/src/lib/LazyRoute.svelte
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<script>
|
||||||
|
import { Route } from "svelte-navigator";
|
||||||
|
import Lazy from "~/lib/Lazy.svelte";
|
||||||
|
|
||||||
|
export let component;
|
||||||
|
export let delayMs = null;
|
||||||
|
|
||||||
|
let props;
|
||||||
|
$: {
|
||||||
|
// eslint-disable-next-line no-shadow
|
||||||
|
const { component, ...restProps } = $$props;
|
||||||
|
props = restProps;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Route {...props}>
|
||||||
|
<Lazy {component} {delayMs}>
|
||||||
|
<slot />
|
||||||
|
</Lazy>
|
||||||
|
</Route>
|
67
desktop/local-app/src/lib/Sidebar.svelte
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
import { Link } from "svelte-navigator";
|
||||||
|
|
||||||
|
import { servers, selectedServer, loadServers } from "~/store";
|
||||||
|
import CogIcon from "~/assets/nes.icons/cog.svg";
|
||||||
|
import { api } from "~/lib/ipc";
|
||||||
|
|
||||||
|
let isDevelopment = false;
|
||||||
|
|
||||||
|
function getServerColor(i: number) {
|
||||||
|
const serverColors = [
|
||||||
|
"bg-red-400",
|
||||||
|
"bg-yellow-500",
|
||||||
|
"bg-green-500",
|
||||||
|
"bg-blue-500",
|
||||||
|
"bg-indigo-500",
|
||||||
|
"bg-purple-500",
|
||||||
|
];
|
||||||
|
|
||||||
|
return serverColors[i % serverColors.length];
|
||||||
|
}
|
||||||
|
|
||||||
|
$: serverWithSelection = $servers.map((s) => ({ ...s, isSelected: $selectedServer === s._id }))
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
|
await loadServers();
|
||||||
|
isDevelopment = await api.isDevelopment();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<aside class="flex flex-col bg-gray-700 items-center">
|
||||||
|
<div class="flex flex-col mt-4 space-y-4 overflow-y-auto pb-4">
|
||||||
|
{#each serverWithSelection as server, i}
|
||||||
|
<Link to="/server/{server._id}" class="flex flex-col items-center justify-center ">
|
||||||
|
<div
|
||||||
|
class={`w-16 h-16 p-1 rounded-md flex cursor-pointer text-light-50 border-4 border-transparent text-gray-200 hover:text-gray-500`}
|
||||||
|
class:bg-gray-400={server.isSelected}
|
||||||
|
>
|
||||||
|
<div class={`flex w-full h-full text-center items-center justify-center rounded-md ${getServerColor(i)}`}>
|
||||||
|
{server.name.slice(0,2).toLocaleUpperCase()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
<Link
|
||||||
|
to="/server/add"
|
||||||
|
class="flex justify-center items-center text-4xl no-underline text-gray-200 cursor-pointer hover:text-gray-500"
|
||||||
|
>+</Link
|
||||||
|
>
|
||||||
|
<Link
|
||||||
|
to="/settings"
|
||||||
|
class="flex mt-auto mb-4 justify-center items-center text-4xl no-underline cursor-pointer"
|
||||||
|
>
|
||||||
|
<CogIcon width="30" height="30" class="fill-gray-200 hover:fill-gray-500" />
|
||||||
|
</Link>
|
||||||
|
{#if isDevelopment}
|
||||||
|
<button class="text-8px text-red-500 my-4" on:click={() => location.reload()}>Refresh</button>
|
||||||
|
{/if}
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
aside {
|
||||||
|
width: 80px;
|
||||||
|
}
|
||||||
|
</style>
|
27
desktop/local-app/src/lib/TextInput.svelte
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { createEventDispatcher } from "svelte";
|
||||||
|
|
||||||
|
export let id: string;
|
||||||
|
export let value: string = "";
|
||||||
|
export let required: boolean = false;
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher<{
|
||||||
|
change: string;
|
||||||
|
}>();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class={`flex items-center w-full h-10 border-1 rounded-md overflow-hidden text-gray-200 text-md appearance-none focus:outline-none`}
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
{id}
|
||||||
|
type="text"
|
||||||
|
class="flex-grow h-full border-none mx-2 bg-transparent appearance-none focus:outline-none"
|
||||||
|
{value}
|
||||||
|
{required}
|
||||||
|
on:change={(e) => {
|
||||||
|
value = e.target.value;
|
||||||
|
dispatch("change", { value });
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
36
desktop/local-app/src/lib/ToggleSwitch.svelte
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { createEventDispatcher } from "svelte";
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
|
export let id: string;
|
||||||
|
export let value: boolean;
|
||||||
|
export let title: string = null;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="flex w-full my-2">
|
||||||
|
<label for={id} class="flex items-center cursor-pointer">
|
||||||
|
<div class="relative">
|
||||||
|
<input
|
||||||
|
{id}
|
||||||
|
type="checkbox"
|
||||||
|
class="sr-only"
|
||||||
|
checked={value}
|
||||||
|
on:change={(e) => {
|
||||||
|
dispatch("change", e.target.checked);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div class="w-10 h-4 bg-gray-400 rounded-full shadow-inner" />
|
||||||
|
<div class="dot absolute w-6 h-6 bg-gray-500 rounded-full shadow -left-1 -top-1 transition" />
|
||||||
|
</div>
|
||||||
|
{#if title}
|
||||||
|
<div class="ml-4 text-gray-200 text-sm">{title}</div>
|
||||||
|
{/if}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
input:checked ~ .dot {
|
||||||
|
transform: translateX(100%);
|
||||||
|
background-color: #0369a1;
|
||||||
|
}
|
||||||
|
</style>
|
5
desktop/local-app/src/lib/ipc.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import type { WorkAdventureLocalAppApi, SettingsData, Server } from "@wa-preload-local-app";
|
||||||
|
|
||||||
|
export { WorkAdventureLocalAppApi, SettingsData, Server };
|
||||||
|
|
||||||
|
export const api = window?.WAD;
|
8
desktop/local-app/src/main.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import "virtual:windi.css";
|
||||||
|
import App from "~/App.svelte";
|
||||||
|
|
||||||
|
const app = new App({
|
||||||
|
target: document.getElementById("app"),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default app;
|
28
desktop/local-app/src/store.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { writable, get } from "svelte/store";
|
||||||
|
import { api, Server } from "~/lib/ipc";
|
||||||
|
|
||||||
|
export const newServer = writable<Omit<Server, "_id">>({
|
||||||
|
name: "",
|
||||||
|
url: "",
|
||||||
|
});
|
||||||
|
export const servers = writable<Server[]>([]);
|
||||||
|
export const selectedServer = writable<string>("");
|
||||||
|
|
||||||
|
export async function selectServer(serverId: string) {
|
||||||
|
await api.selectServer(serverId);
|
||||||
|
selectedServer.set(serverId);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function addServer() {
|
||||||
|
const addedServer = await api.addServer(get(newServer));
|
||||||
|
if (addedServer instanceof Error) {
|
||||||
|
throw new Error(addedServer as unknown as string);
|
||||||
|
}
|
||||||
|
newServer.set({ name: "", url: "" });
|
||||||
|
servers.update((s) => [...s, addedServer]);
|
||||||
|
await selectServer(addedServer._id);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function loadServers() {
|
||||||
|
servers.set(await api.getServers());
|
||||||
|
}
|
4
desktop/local-app/src/svg.d.ts
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
declare module "*.svg" {
|
||||||
|
const content: string;
|
||||||
|
export default content;
|
||||||
|
}
|
35
desktop/local-app/src/views/AddServer.svelte
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import InputField from "~/lib/InputField.svelte";
|
||||||
|
import TextInput from "~/lib/TextInput.svelte";
|
||||||
|
|
||||||
|
import { newServer, addServer } from "~/store";
|
||||||
|
|
||||||
|
let error = "";
|
||||||
|
async function _addServer() {
|
||||||
|
try {
|
||||||
|
await addServer();
|
||||||
|
} catch(e) {
|
||||||
|
console.log(e);
|
||||||
|
error = e.message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="flex w-full h-full justify-center items-center">
|
||||||
|
<form class="flex flex-col justify-center" on:submit|preventDefault={_addServer}>
|
||||||
|
<InputField title="Name" id="name">
|
||||||
|
<TextInput bind:value={$newServer.name} required id="name" />
|
||||||
|
</InputField>
|
||||||
|
<InputField title="Url" id="url">
|
||||||
|
<TextInput bind:value={$newServer.url} required id="url" />
|
||||||
|
</InputField>
|
||||||
|
{#if error}
|
||||||
|
<div class="text-red-500 text-center mb-2">{error}</div>
|
||||||
|
{/if}
|
||||||
|
<input
|
||||||
|
type="submit"
|
||||||
|
value="Add server"
|
||||||
|
class="mt-4 rounded-md p-2 bg-gray-300 cursor-pointer hover:bg-gray-400"
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
</div>
|
19
desktop/local-app/src/views/Home.svelte
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
|
||||||
|
import Logo from "~/../../electron/assets/icons/logo.svg";
|
||||||
|
import { api } from "~/lib/ipc";
|
||||||
|
|
||||||
|
let version = "";
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
|
version = await api.getVersion();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="flex flex-col w-full h-full justify-center items-center">
|
||||||
|
<Logo height="100" class="my-auto" />
|
||||||
|
<div class="flex my-4 items-center space-x-4">
|
||||||
|
<span class="text-gray-300 text-lg ">Desktop-App Version: {version}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
21
desktop/local-app/src/views/Server.svelte
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { onDestroy, onMount } from "svelte";
|
||||||
|
import { useParams } from "svelte-navigator";
|
||||||
|
|
||||||
|
import { selectServer, servers } from "~/store";
|
||||||
|
import { api } from "~/lib/ipc";
|
||||||
|
|
||||||
|
const params = useParams();
|
||||||
|
|
||||||
|
params.subscribe((_params) => {
|
||||||
|
selectServer(_params.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
onDestroy(async () => {
|
||||||
|
await api.showLocalApp();
|
||||||
|
});
|
||||||
|
|
||||||
|
$: server = $servers.find(({ _id }) => _id === $params.id);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="hidden m-auto text-gray-400">Server: "{server.name}"</div>
|
75
desktop/local-app/src/views/Settings.svelte
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { onMount, onDestroy } from "svelte";
|
||||||
|
import { writable, get } from "svelte/store";
|
||||||
|
|
||||||
|
import ToggleSwitch from "~/lib/ToggleSwitch.svelte";
|
||||||
|
import InputField from "~/lib/InputField.svelte";
|
||||||
|
import KeyRecord from "~/lib/KeyRecord.svelte";
|
||||||
|
import { api, SettingsData } from "../lib/ipc";
|
||||||
|
|
||||||
|
const settings = writable<SettingsData | undefined>();
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
|
await api.setShortcutsEnabled(false);
|
||||||
|
$settings = await api.getSettings();
|
||||||
|
});
|
||||||
|
|
||||||
|
onDestroy(async () => {
|
||||||
|
await api.setShortcutsEnabled(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
async function saveShortcut(key: keyof SettingsData["shortcuts"], value: string) {
|
||||||
|
const shortcuts = get(settings)['shortcuts'];
|
||||||
|
shortcuts[key] = value;
|
||||||
|
settings.update((s) => ({ ...s, shortcuts }));
|
||||||
|
await api.saveSetting("shortcuts", shortcuts);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function saveAutoLaunch(auto_launch_enabled: boolean) {
|
||||||
|
settings.update((s) => ({ ...s, auto_launch_enabled }));
|
||||||
|
await api.saveSetting("auto_launch_enabled", auto_launch_enabled);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="flex flex-col w-full h-full justify-center items-center">
|
||||||
|
<h1 class="text-gray-200 text-2xl mb-6">Settings</h1>
|
||||||
|
|
||||||
|
<div class="flex flex-col justify-start max-w-148">
|
||||||
|
{#if $settings}
|
||||||
|
<InputField
|
||||||
|
id="toggle-camera"
|
||||||
|
title="Toggle Mute"
|
||||||
|
description="Set a shortcut to turn your microphone on and off"
|
||||||
|
>
|
||||||
|
<KeyRecord
|
||||||
|
id="toggle-mute"
|
||||||
|
value={$settings.shortcuts.mute_toggle}
|
||||||
|
on:change={(e) => saveShortcut("mute_toggle", e.detail)}
|
||||||
|
/>
|
||||||
|
</InputField>
|
||||||
|
|
||||||
|
<InputField
|
||||||
|
id="toggle-camera"
|
||||||
|
title="Toggle Camera"
|
||||||
|
description="Set a shortcut to turn your camera on and off"
|
||||||
|
>
|
||||||
|
<KeyRecord
|
||||||
|
id="toggle-camera"
|
||||||
|
value={$settings.shortcuts.camera_toggle}
|
||||||
|
on:change={(e) => saveShortcut("camera_toggle", e.detail)}
|
||||||
|
/>
|
||||||
|
</InputField>
|
||||||
|
|
||||||
|
<InputField id="toggle-autostart" title="Toggle autostart">
|
||||||
|
<ToggleSwitch
|
||||||
|
id="toggle-autostart"
|
||||||
|
value={$settings.auto_launch_enabled}
|
||||||
|
title="Autostart WorkAdventure after your PC started"
|
||||||
|
on:change={(e) => saveAutoLaunch(e.detail)}
|
||||||
|
/>
|
||||||
|
</InputField>
|
||||||
|
|
||||||
|
<span class="mt-8 text-xs text-gray-200 max-w-128">Hint: Shortcuts are disabled while seeing this page</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
2
desktop/local-app/src/vite-env.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/// <reference types="svelte" />
|
||||||
|
/// <reference types="vite/client" />
|
7
desktop/local-app/src/window.d.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import type { WorkAdventureLocalAppApi } from "@wa-preload-local-app";
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
WAD: WorkAdventureLocalAppApi;
|
||||||
|
}
|
||||||
|
}
|
7
desktop/local-app/svelte.config.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import sveltePreprocess from 'svelte-preprocess'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
// Consult https://github.com/sveltejs/svelte-preprocess
|
||||||
|
// for more information about preprocessors
|
||||||
|
preprocess: sveltePreprocess()
|
||||||
|
}
|
24
desktop/local-app/tsconfig.json
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"extends": "@tsconfig/svelte/tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "esnext",
|
||||||
|
"useDefineForClassFields": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"baseUrl": ".",
|
||||||
|
/**
|
||||||
|
* Typecheck JS in `.svelte` and `.js` files by default.
|
||||||
|
* Disable checkJs if you'd like to use dynamic types in JS.
|
||||||
|
* Note that setting allowJs false does not prevent the use
|
||||||
|
* of JS in `.svelte` files.
|
||||||
|
*/
|
||||||
|
"allowJs": true,
|
||||||
|
"checkJs": true,
|
||||||
|
"paths": {
|
||||||
|
"~/*": ["./src/*"],
|
||||||
|
"@wa-preload-local-app": ["../electron/src/preload-local-app/types.ts"],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"],
|
||||||
|
"references": [{ "path": "./tsconfig.node.json" }]
|
||||||
|
}
|
9
desktop/local-app/tsconfig.node.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"composite": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"allowSyntheticDefaultImports": true
|
||||||
|
},
|
||||||
|
"include": ["vite.config.ts"]
|
||||||
|
}
|
26
desktop/local-app/vite.config.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { defineConfig } from "vite";
|
||||||
|
import { svelte } from "@sveltejs/vite-plugin-svelte";
|
||||||
|
import WindiCSS from "vite-plugin-windicss";
|
||||||
|
import { svelteSVG } from "rollup-plugin-svelte-svg";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
"~": `${path.resolve(__dirname, "src")}/`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
svelte(),
|
||||||
|
svelteSVG({
|
||||||
|
// optional SVGO options
|
||||||
|
// pass empty object to enable defaults
|
||||||
|
svgo: {},
|
||||||
|
// vite-specific
|
||||||
|
// https://vitejs.dev/guide/api-plugin.html#plugin-ordering
|
||||||
|
// enforce: 'pre' | 'post'
|
||||||
|
enforce: "pre",
|
||||||
|
}),
|
||||||
|
WindiCSS(),
|
||||||
|
],
|
||||||
|
});
|
940
desktop/local-app/yarn.lock
Normal file
@ -0,0 +1,940 @@
|
|||||||
|
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||||
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
"@16bits/nes.css@^2.3.2":
|
||||||
|
version "2.3.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@16bits/nes.css/-/nes.css-2.3.2.tgz#e69db834119b33ae8d3cb044f106a07a17cadd6f"
|
||||||
|
integrity sha512-nEM5PIth+Bab5JSOa4uUR+PMNUsNTYxA55oVlG3gXI/4LoYtWS767Uv9Pu/KCbHXVvnIjt4ZXt13kZw3083qTw==
|
||||||
|
|
||||||
|
"@antfu/utils@^0.4.0":
|
||||||
|
version "0.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@antfu/utils/-/utils-0.4.0.tgz#df100ed9922d7359bf6c99083765b5207086b9a7"
|
||||||
|
integrity sha512-gqkpvjkgFUu+s3kP+Ly33OKpo5zvVY3FDFhv5BIb98SncS3KD6DNxPfNDjwHIoyXbz1leWo1j8DtRLZ1D2Jv+Q==
|
||||||
|
dependencies:
|
||||||
|
"@types/throttle-debounce" "^2.1.0"
|
||||||
|
|
||||||
|
"@fontsource/press-start-2p@^4.5.2":
|
||||||
|
version "4.5.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@fontsource/press-start-2p/-/press-start-2p-4.5.2.tgz#062d56ce6dcffdd28f8ca80d9e5b86a473a37c15"
|
||||||
|
integrity sha512-1Wwk85zlUiirPTIw25V3z4wLXbrqaOqDV7g5akjPuthg+hY5Wv0zOPXcHRVBwb+Igh4qVLHUd6O5X27BgWTbkg==
|
||||||
|
|
||||||
|
"@nodelib/fs.scandir@2.1.5":
|
||||||
|
version "2.1.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
|
||||||
|
integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==
|
||||||
|
dependencies:
|
||||||
|
"@nodelib/fs.stat" "2.0.5"
|
||||||
|
run-parallel "^1.1.9"
|
||||||
|
|
||||||
|
"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2":
|
||||||
|
version "2.0.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b"
|
||||||
|
integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
|
||||||
|
|
||||||
|
"@nodelib/fs.walk@^1.2.3":
|
||||||
|
version "1.2.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a"
|
||||||
|
integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==
|
||||||
|
dependencies:
|
||||||
|
"@nodelib/fs.scandir" "2.1.5"
|
||||||
|
fastq "^1.6.0"
|
||||||
|
|
||||||
|
"@rollup/pluginutils@^4.1.2":
|
||||||
|
version "4.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.1.2.tgz#ed5821c15e5e05e32816f5fb9ec607cdf5a75751"
|
||||||
|
integrity sha512-ROn4qvkxP9SyPeHaf7uQC/GPFY6L/OWy9+bd9AwcjOAWQwxRscoEyAUD8qCY5o5iL4jqQwoLk2kaTKJPb/HwzQ==
|
||||||
|
dependencies:
|
||||||
|
estree-walker "^2.0.1"
|
||||||
|
picomatch "^2.2.2"
|
||||||
|
|
||||||
|
"@sveltejs/vite-plugin-svelte@^1.0.0-next.30":
|
||||||
|
version "1.0.0-next.37"
|
||||||
|
resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.0.0-next.37.tgz#bb553425a3f9b780221134b04b9ace4165279d3c"
|
||||||
|
integrity sha512-EdSXw2rXeOahNrQfMJVZxa/NxZxW1a0TiBI3s+pVxnxU14hEQtnkLtdbTFhnceu22gJpNPFSIJRcIwRBBDQIeA==
|
||||||
|
dependencies:
|
||||||
|
"@rollup/pluginutils" "^4.1.2"
|
||||||
|
debug "^4.3.3"
|
||||||
|
kleur "^4.1.4"
|
||||||
|
magic-string "^0.25.7"
|
||||||
|
svelte-hmr "^0.14.9"
|
||||||
|
|
||||||
|
"@trysound/sax@0.2.0":
|
||||||
|
version "0.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad"
|
||||||
|
integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==
|
||||||
|
|
||||||
|
"@tsconfig/svelte@^2.0.1":
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@tsconfig/svelte/-/svelte-2.0.1.tgz#0e8d7caa693e9b2afce5e622c0475bb0fd89c12c"
|
||||||
|
integrity sha512-aqkICXbM1oX5FfgZd2qSSAGdyo/NRxjWCamxoyi3T8iVQnzGge19HhDYzZ6NrVOW7bhcWNSq9XexWFtMzbB24A==
|
||||||
|
|
||||||
|
"@types/node@*":
|
||||||
|
version "17.0.18"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.18.tgz#3b4fed5cfb58010e3a2be4b6e74615e4847f1074"
|
||||||
|
integrity sha512-eKj4f/BsN/qcculZiRSujogjvp5O/k4lOW5m35NopjZM/QwLOR075a8pJW5hD+Rtdm2DaCVPENS6KtSQnUD6BA==
|
||||||
|
|
||||||
|
"@types/pug@^2.0.4":
|
||||||
|
version "2.0.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/pug/-/pug-2.0.6.tgz#f830323c88172e66826d0bde413498b61054b5a6"
|
||||||
|
integrity sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==
|
||||||
|
|
||||||
|
"@types/sass@^1.16.0":
|
||||||
|
version "1.43.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/sass/-/sass-1.43.1.tgz#86bb0168e9e881d7dade6eba16c9ed6d25dc2f68"
|
||||||
|
integrity sha512-BPdoIt1lfJ6B7rw35ncdwBZrAssjcwzI5LByIrYs+tpXlj/CAkuVdRsgZDdP4lq5EjyWzwxZCqAoFyHKFwp32g==
|
||||||
|
dependencies:
|
||||||
|
"@types/node" "*"
|
||||||
|
|
||||||
|
"@types/throttle-debounce@^2.1.0":
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/throttle-debounce/-/throttle-debounce-2.1.0.tgz#1c3df624bfc4b62f992d3012b84c56d41eab3776"
|
||||||
|
integrity sha512-5eQEtSCoESnh2FsiLTxE121IiE60hnMqcb435fShf4bpLRjEu1Eoekht23y6zXS9Ts3l+Szu3TARnTsA0GkOkQ==
|
||||||
|
|
||||||
|
"@windicss/config@1.7.1":
|
||||||
|
version "1.7.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@windicss/config/-/config-1.7.1.tgz#f0c432796bff75bad58c72f168329fbe34619025"
|
||||||
|
integrity sha512-bT4Ze8d1kTKbVdQZ7yal9vjhIfuYypco2gVTy4OXvg6eAHFNZaOB/Ai4FqdRKvbgOqChHGiC32r5J55hmq6tDw==
|
||||||
|
dependencies:
|
||||||
|
debug "^4.3.3"
|
||||||
|
jiti "^1.12.9"
|
||||||
|
windicss "^3.4.3"
|
||||||
|
|
||||||
|
"@windicss/plugin-utils@1.7.1":
|
||||||
|
version "1.7.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@windicss/plugin-utils/-/plugin-utils-1.7.1.tgz#f1d5ac3d0d437d88c93ee4ea575c41907537523d"
|
||||||
|
integrity sha512-VMBLZ11s5kQt1RIIwfB45xFswb+SI1cvI5mK07dUSlfpomG1d1bqnB57bioo/jFNZh2Rl8wVnEvLTl7iZ4r09Q==
|
||||||
|
dependencies:
|
||||||
|
"@antfu/utils" "^0.4.0"
|
||||||
|
"@windicss/config" "1.7.1"
|
||||||
|
debug "^4.3.3"
|
||||||
|
fast-glob "^3.2.11"
|
||||||
|
magic-string "^0.25.7"
|
||||||
|
micromatch "^4.0.4"
|
||||||
|
windicss "^3.4.3"
|
||||||
|
|
||||||
|
anymatch@~3.1.2:
|
||||||
|
version "3.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716"
|
||||||
|
integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==
|
||||||
|
dependencies:
|
||||||
|
normalize-path "^3.0.0"
|
||||||
|
picomatch "^2.0.4"
|
||||||
|
|
||||||
|
balanced-match@^1.0.0:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||||
|
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||||
|
|
||||||
|
binary-extensions@^2.0.0:
|
||||||
|
version "2.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
|
||||||
|
integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
|
||||||
|
|
||||||
|
boolbase@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
|
||||||
|
integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
|
||||||
|
|
||||||
|
brace-expansion@^1.1.7:
|
||||||
|
version "1.1.11"
|
||||||
|
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||||
|
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
|
||||||
|
dependencies:
|
||||||
|
balanced-match "^1.0.0"
|
||||||
|
concat-map "0.0.1"
|
||||||
|
|
||||||
|
braces@^3.0.1, braces@~3.0.2:
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
|
||||||
|
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
|
||||||
|
dependencies:
|
||||||
|
fill-range "^7.0.1"
|
||||||
|
|
||||||
|
buffer-crc32@^0.2.5:
|
||||||
|
version "0.2.13"
|
||||||
|
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
|
||||||
|
integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=
|
||||||
|
|
||||||
|
callsites@^3.0.0:
|
||||||
|
version "3.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
|
||||||
|
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
|
||||||
|
|
||||||
|
chokidar@^3.4.1:
|
||||||
|
version "3.5.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
|
||||||
|
integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
|
||||||
|
dependencies:
|
||||||
|
anymatch "~3.1.2"
|
||||||
|
braces "~3.0.2"
|
||||||
|
glob-parent "~5.1.2"
|
||||||
|
is-binary-path "~2.1.0"
|
||||||
|
is-glob "~4.0.1"
|
||||||
|
normalize-path "~3.0.0"
|
||||||
|
readdirp "~3.6.0"
|
||||||
|
optionalDependencies:
|
||||||
|
fsevents "~2.3.2"
|
||||||
|
|
||||||
|
commander@^7.2.0:
|
||||||
|
version "7.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7"
|
||||||
|
integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==
|
||||||
|
|
||||||
|
concat-map@0.0.1:
|
||||||
|
version "0.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||||
|
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||||
|
|
||||||
|
css-select@^4.1.3:
|
||||||
|
version "4.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.2.1.tgz#9e665d6ae4c7f9d65dbe69d0316e3221fb274cdd"
|
||||||
|
integrity sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==
|
||||||
|
dependencies:
|
||||||
|
boolbase "^1.0.0"
|
||||||
|
css-what "^5.1.0"
|
||||||
|
domhandler "^4.3.0"
|
||||||
|
domutils "^2.8.0"
|
||||||
|
nth-check "^2.0.1"
|
||||||
|
|
||||||
|
css-tree@^1.1.2, css-tree@^1.1.3:
|
||||||
|
version "1.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d"
|
||||||
|
integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==
|
||||||
|
dependencies:
|
||||||
|
mdn-data "2.0.14"
|
||||||
|
source-map "^0.6.1"
|
||||||
|
|
||||||
|
css-what@^5.1.0:
|
||||||
|
version "5.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.1.0.tgz#3f7b707aadf633baf62c2ceb8579b545bb40f7fe"
|
||||||
|
integrity sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==
|
||||||
|
|
||||||
|
csso@^4.2.0:
|
||||||
|
version "4.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529"
|
||||||
|
integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==
|
||||||
|
dependencies:
|
||||||
|
css-tree "^1.1.2"
|
||||||
|
|
||||||
|
debug@^4.3.3:
|
||||||
|
version "4.3.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664"
|
||||||
|
integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==
|
||||||
|
dependencies:
|
||||||
|
ms "2.1.2"
|
||||||
|
|
||||||
|
dedent-js@^1.0.1:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/dedent-js/-/dedent-js-1.0.1.tgz#bee5fb7c9e727d85dffa24590d10ec1ab1255305"
|
||||||
|
integrity sha1-vuX7fJ5yfYXf+iRZDRDsGrElUwU=
|
||||||
|
|
||||||
|
detect-indent@^6.0.0:
|
||||||
|
version "6.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.1.0.tgz#592485ebbbf6b3b1ab2be175c8393d04ca0d57e6"
|
||||||
|
integrity sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==
|
||||||
|
|
||||||
|
dom-serializer@^1.0.1:
|
||||||
|
version "1.3.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91"
|
||||||
|
integrity sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==
|
||||||
|
dependencies:
|
||||||
|
domelementtype "^2.0.1"
|
||||||
|
domhandler "^4.2.0"
|
||||||
|
entities "^2.0.0"
|
||||||
|
|
||||||
|
domelementtype@^2.0.1, domelementtype@^2.2.0:
|
||||||
|
version "2.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57"
|
||||||
|
integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==
|
||||||
|
|
||||||
|
domhandler@^4.2.0, domhandler@^4.3.0:
|
||||||
|
version "4.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.0.tgz#16c658c626cf966967e306f966b431f77d4a5626"
|
||||||
|
integrity sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==
|
||||||
|
dependencies:
|
||||||
|
domelementtype "^2.2.0"
|
||||||
|
|
||||||
|
domutils@^2.8.0:
|
||||||
|
version "2.8.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135"
|
||||||
|
integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==
|
||||||
|
dependencies:
|
||||||
|
dom-serializer "^1.0.1"
|
||||||
|
domelementtype "^2.2.0"
|
||||||
|
domhandler "^4.2.0"
|
||||||
|
|
||||||
|
entities@^2.0.0:
|
||||||
|
version "2.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
|
||||||
|
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
|
||||||
|
|
||||||
|
es6-promise@^3.1.2:
|
||||||
|
version "3.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613"
|
||||||
|
integrity sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=
|
||||||
|
|
||||||
|
esbuild-android-arm64@0.14.23:
|
||||||
|
version "0.14.23"
|
||||||
|
resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.23.tgz#c89b3c50b4f47668dcbeb0b34ee4615258818e71"
|
||||||
|
integrity sha512-k9sXem++mINrZty1v4FVt6nC5BQCFG4K2geCIUUqHNlTdFnuvcqsY7prcKZLFhqVC1rbcJAr9VSUGFL/vD4vsw==
|
||||||
|
|
||||||
|
esbuild-darwin-64@0.14.23:
|
||||||
|
version "0.14.23"
|
||||||
|
resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.23.tgz#1c131e8cb133ed935ca32f824349a117c896a15b"
|
||||||
|
integrity sha512-lB0XRbtOYYL1tLcYw8BoBaYsFYiR48RPrA0KfA/7RFTr4MV7Bwy/J4+7nLsVnv9FGuQummM3uJ93J3ptaTqFug==
|
||||||
|
|
||||||
|
esbuild-darwin-arm64@0.14.23:
|
||||||
|
version "0.14.23"
|
||||||
|
resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.23.tgz#3c6245a50109dd84953f53d7833bd3b4f0e8c6fa"
|
||||||
|
integrity sha512-yat73Z/uJ5tRcfRiI4CCTv0FSnwErm3BJQeZAh+1tIP0TUNh6o+mXg338Zl5EKChD+YGp6PN+Dbhs7qa34RxSw==
|
||||||
|
|
||||||
|
esbuild-freebsd-64@0.14.23:
|
||||||
|
version "0.14.23"
|
||||||
|
resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.23.tgz#0cdc54e72d3dd9cd992f9c2960055e68a7f8650c"
|
||||||
|
integrity sha512-/1xiTjoLuQ+LlbfjJdKkX45qK/M7ARrbLmyf7x3JhyQGMjcxRYVR6Dw81uH3qlMHwT4cfLW4aEVBhP1aNV7VsA==
|
||||||
|
|
||||||
|
esbuild-freebsd-arm64@0.14.23:
|
||||||
|
version "0.14.23"
|
||||||
|
resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.23.tgz#1d11faed3a0c429e99b7dddef84103eb509788b2"
|
||||||
|
integrity sha512-uyPqBU/Zcp6yEAZS4LKj5jEE0q2s4HmlMBIPzbW6cTunZ8cyvjG6YWpIZXb1KK3KTJDe62ltCrk3VzmWHp+iLg==
|
||||||
|
|
||||||
|
esbuild-linux-32@0.14.23:
|
||||||
|
version "0.14.23"
|
||||||
|
resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.23.tgz#fd9f033fc27dcab61100cb1eb1c936893a68c841"
|
||||||
|
integrity sha512-37R/WMkQyUfNhbH7aJrr1uCjDVdnPeTHGeDhZPUNhfoHV0lQuZNCKuNnDvlH/u/nwIYZNdVvz1Igv5rY/zfrzQ==
|
||||||
|
|
||||||
|
esbuild-linux-64@0.14.23:
|
||||||
|
version "0.14.23"
|
||||||
|
resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.23.tgz#c04c438514f1359ecb1529205d0c836d4165f198"
|
||||||
|
integrity sha512-H0gztDP60qqr8zoFhAO64waoN5yBXkmYCElFklpd6LPoobtNGNnDe99xOQm28+fuD75YJ7GKHzp/MLCLhw2+vQ==
|
||||||
|
|
||||||
|
esbuild-linux-arm64@0.14.23:
|
||||||
|
version "0.14.23"
|
||||||
|
resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.23.tgz#d1b3ab2988ab0734886eb9e811726f7db099ab96"
|
||||||
|
integrity sha512-c4MLOIByNHR55n3KoYf9hYDfBRghMjOiHLaoYLhkQkIabb452RWi+HsNgB41sUpSlOAqfpqKPFNg7VrxL3UX9g==
|
||||||
|
|
||||||
|
esbuild-linux-arm@0.14.23:
|
||||||
|
version "0.14.23"
|
||||||
|
resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.23.tgz#df7558b6a5076f5eb9fd387c8704f768b61d97fb"
|
||||||
|
integrity sha512-x64CEUxi8+EzOAIpCUeuni0bZfzPw/65r8tC5cy5zOq9dY7ysOi5EVQHnzaxS+1NmV+/RVRpmrzGw1QgY2Xpmw==
|
||||||
|
|
||||||
|
esbuild-linux-mips64le@0.14.23:
|
||||||
|
version "0.14.23"
|
||||||
|
resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.23.tgz#bb4c47fccc9493d460ffeb1f88e8a97a98a14f8b"
|
||||||
|
integrity sha512-kHKyKRIAedYhKug2EJpyJxOUj3VYuamOVA1pY7EimoFPzaF3NeY7e4cFBAISC/Av0/tiV0xlFCt9q0HJ68IBIw==
|
||||||
|
|
||||||
|
esbuild-linux-ppc64le@0.14.23:
|
||||||
|
version "0.14.23"
|
||||||
|
resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.23.tgz#a332dbc8a1b4e30cfe1261bfaa5cef57c9c8c02a"
|
||||||
|
integrity sha512-7ilAiJEPuJJnJp/LiDO0oJm5ygbBPzhchJJh9HsHZzeqO+3PUzItXi+8PuicY08r0AaaOe25LA7sGJ0MzbfBag==
|
||||||
|
|
||||||
|
esbuild-linux-riscv64@0.14.23:
|
||||||
|
version "0.14.23"
|
||||||
|
resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.23.tgz#85675f3f931f5cd7cfb238fd82f77a62ffcb6d86"
|
||||||
|
integrity sha512-fbL3ggK2wY0D8I5raPIMPhpCvODFE+Bhb5QGtNP3r5aUsRR6TQV+ZBXIaw84iyvKC8vlXiA4fWLGhghAd/h/Zg==
|
||||||
|
|
||||||
|
esbuild-linux-s390x@0.14.23:
|
||||||
|
version "0.14.23"
|
||||||
|
resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.23.tgz#a526282a696e6d846f4c628f5315475518c0c0f0"
|
||||||
|
integrity sha512-GHMDCyfy7+FaNSO8RJ8KCFsnax8fLUsOrj9q5Gi2JmZMY0Zhp75keb5abTFCq2/Oy6KVcT0Dcbyo/bFb4rIFJA==
|
||||||
|
|
||||||
|
esbuild-netbsd-64@0.14.23:
|
||||||
|
version "0.14.23"
|
||||||
|
resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.23.tgz#8e456605694719aa1be4be266d6cd569c06dfaf5"
|
||||||
|
integrity sha512-ovk2EX+3rrO1M2lowJfgMb/JPN1VwVYrx0QPUyudxkxLYrWeBxDKQvc6ffO+kB4QlDyTfdtAURrVzu3JeNdA2g==
|
||||||
|
|
||||||
|
esbuild-openbsd-64@0.14.23:
|
||||||
|
version "0.14.23"
|
||||||
|
resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.23.tgz#f2fc51714b4ddabc86e4eb30ca101dd325db2f7d"
|
||||||
|
integrity sha512-uYYNqbVR+i7k8ojP/oIROAHO9lATLN7H2QeXKt2H310Fc8FJj4y3Wce6hx0VgnJ4k1JDrgbbiXM8rbEgQyg8KA==
|
||||||
|
|
||||||
|
esbuild-sunos-64@0.14.23:
|
||||||
|
version "0.14.23"
|
||||||
|
resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.23.tgz#a408f33ea20e215909e20173a0fd78b1aaad1f8e"
|
||||||
|
integrity sha512-hAzeBeET0+SbScknPzS2LBY6FVDpgE+CsHSpe6CEoR51PApdn2IB0SyJX7vGelXzlyrnorM4CAsRyb9Qev4h9g==
|
||||||
|
|
||||||
|
esbuild-windows-32@0.14.23:
|
||||||
|
version "0.14.23"
|
||||||
|
resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.23.tgz#b9005bbff54dac3975ff355d5de2b5e37165d128"
|
||||||
|
integrity sha512-Kttmi3JnohdaREbk6o9e25kieJR379TsEWF0l39PQVHXq3FR6sFKtVPgY8wk055o6IB+rllrzLnbqOw/UV60EA==
|
||||||
|
|
||||||
|
esbuild-windows-64@0.14.23:
|
||||||
|
version "0.14.23"
|
||||||
|
resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.23.tgz#2b5a99befeaca6aefdad32d738b945730a60a060"
|
||||||
|
integrity sha512-JtIT0t8ymkpl6YlmOl6zoSWL5cnCgyLaBdf/SiU/Eg3C13r0NbHZWNT/RDEMKK91Y6t79kTs3vyRcNZbfu5a8g==
|
||||||
|
|
||||||
|
esbuild-windows-arm64@0.14.23:
|
||||||
|
version "0.14.23"
|
||||||
|
resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.23.tgz#edc560bbadb097eb45fc235aeacb942cb94a38c0"
|
||||||
|
integrity sha512-cTFaQqT2+ik9e4hePvYtRZQ3pqOvKDVNarzql0VFIzhc0tru/ZgdLoXd6epLiKT+SzoSce6V9YJ+nn6RCn6SHw==
|
||||||
|
|
||||||
|
esbuild@^0.14.14:
|
||||||
|
version "0.14.23"
|
||||||
|
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.23.tgz#95e842cb22bc0c7d82c140adc16788aac91469fe"
|
||||||
|
integrity sha512-XjnIcZ9KB6lfonCa+jRguXyRYcldmkyZ99ieDksqW/C8bnyEX299yA4QH2XcgijCgaddEZePPTgvx/2imsq7Ig==
|
||||||
|
optionalDependencies:
|
||||||
|
esbuild-android-arm64 "0.14.23"
|
||||||
|
esbuild-darwin-64 "0.14.23"
|
||||||
|
esbuild-darwin-arm64 "0.14.23"
|
||||||
|
esbuild-freebsd-64 "0.14.23"
|
||||||
|
esbuild-freebsd-arm64 "0.14.23"
|
||||||
|
esbuild-linux-32 "0.14.23"
|
||||||
|
esbuild-linux-64 "0.14.23"
|
||||||
|
esbuild-linux-arm "0.14.23"
|
||||||
|
esbuild-linux-arm64 "0.14.23"
|
||||||
|
esbuild-linux-mips64le "0.14.23"
|
||||||
|
esbuild-linux-ppc64le "0.14.23"
|
||||||
|
esbuild-linux-riscv64 "0.14.23"
|
||||||
|
esbuild-linux-s390x "0.14.23"
|
||||||
|
esbuild-netbsd-64 "0.14.23"
|
||||||
|
esbuild-openbsd-64 "0.14.23"
|
||||||
|
esbuild-sunos-64 "0.14.23"
|
||||||
|
esbuild-windows-32 "0.14.23"
|
||||||
|
esbuild-windows-64 "0.14.23"
|
||||||
|
esbuild-windows-arm64 "0.14.23"
|
||||||
|
|
||||||
|
estree-walker@^0.6.1:
|
||||||
|
version "0.6.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362"
|
||||||
|
integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==
|
||||||
|
|
||||||
|
estree-walker@^2.0.1:
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
|
||||||
|
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
|
||||||
|
|
||||||
|
fast-glob@^3.2.11, fast-glob@^3.2.7:
|
||||||
|
version "3.2.11"
|
||||||
|
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9"
|
||||||
|
integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==
|
||||||
|
dependencies:
|
||||||
|
"@nodelib/fs.stat" "^2.0.2"
|
||||||
|
"@nodelib/fs.walk" "^1.2.3"
|
||||||
|
glob-parent "^5.1.2"
|
||||||
|
merge2 "^1.3.0"
|
||||||
|
micromatch "^4.0.4"
|
||||||
|
|
||||||
|
fastq@^1.6.0:
|
||||||
|
version "1.13.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c"
|
||||||
|
integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==
|
||||||
|
dependencies:
|
||||||
|
reusify "^1.0.4"
|
||||||
|
|
||||||
|
fill-range@^7.0.1:
|
||||||
|
version "7.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
|
||||||
|
integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
|
||||||
|
dependencies:
|
||||||
|
to-regex-range "^5.0.1"
|
||||||
|
|
||||||
|
fs.realpath@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||||
|
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
|
||||||
|
|
||||||
|
fsevents@~2.3.2:
|
||||||
|
version "2.3.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
|
||||||
|
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
|
||||||
|
|
||||||
|
function-bind@^1.1.1:
|
||||||
|
version "1.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
||||||
|
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
|
||||||
|
|
||||||
|
glob-parent@^5.1.2, glob-parent@~5.1.2:
|
||||||
|
version "5.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
|
||||||
|
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
|
||||||
|
dependencies:
|
||||||
|
is-glob "^4.0.1"
|
||||||
|
|
||||||
|
glob@^7.1.3:
|
||||||
|
version "7.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
|
||||||
|
integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
|
||||||
|
dependencies:
|
||||||
|
fs.realpath "^1.0.0"
|
||||||
|
inflight "^1.0.4"
|
||||||
|
inherits "2"
|
||||||
|
minimatch "^3.0.4"
|
||||||
|
once "^1.3.0"
|
||||||
|
path-is-absolute "^1.0.0"
|
||||||
|
|
||||||
|
graceful-fs@^4.1.3:
|
||||||
|
version "4.2.9"
|
||||||
|
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96"
|
||||||
|
integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==
|
||||||
|
|
||||||
|
has@^1.0.3:
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
|
||||||
|
integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
|
||||||
|
dependencies:
|
||||||
|
function-bind "^1.1.1"
|
||||||
|
|
||||||
|
import-fresh@^3.2.1:
|
||||||
|
version "3.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
|
||||||
|
integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==
|
||||||
|
dependencies:
|
||||||
|
parent-module "^1.0.0"
|
||||||
|
resolve-from "^4.0.0"
|
||||||
|
|
||||||
|
inflight@^1.0.4:
|
||||||
|
version "1.0.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
||||||
|
integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
|
||||||
|
dependencies:
|
||||||
|
once "^1.3.0"
|
||||||
|
wrappy "1"
|
||||||
|
|
||||||
|
inherits@2:
|
||||||
|
version "2.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||||
|
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||||
|
|
||||||
|
is-binary-path@~2.1.0:
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
|
||||||
|
integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
|
||||||
|
dependencies:
|
||||||
|
binary-extensions "^2.0.0"
|
||||||
|
|
||||||
|
is-core-module@^2.8.1:
|
||||||
|
version "2.8.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211"
|
||||||
|
integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==
|
||||||
|
dependencies:
|
||||||
|
has "^1.0.3"
|
||||||
|
|
||||||
|
is-extglob@^2.1.1:
|
||||||
|
version "2.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
||||||
|
integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
|
||||||
|
|
||||||
|
is-glob@^4.0.1, is-glob@~4.0.1:
|
||||||
|
version "4.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
|
||||||
|
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
|
||||||
|
dependencies:
|
||||||
|
is-extglob "^2.1.1"
|
||||||
|
|
||||||
|
is-number@^7.0.0:
|
||||||
|
version "7.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
|
||||||
|
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
|
||||||
|
|
||||||
|
jiti@^1.12.9:
|
||||||
|
version "1.13.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.13.0.tgz#3cdfc4e651ca0cca4c62ed5e47747b5841d41a8e"
|
||||||
|
integrity sha512-/n9mNxZj/HDSrincJ6RP+L+yXbpnB8FybySBa+IjIaoH9FIxBbrbRT5XUbe8R7zuVM2AQqNMNDDqz0bzx3znOQ==
|
||||||
|
|
||||||
|
kleur@^4.1.4:
|
||||||
|
version "4.1.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.4.tgz#8c202987d7e577766d039a8cd461934c01cda04d"
|
||||||
|
integrity sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA==
|
||||||
|
|
||||||
|
kolorist@^1.5.1:
|
||||||
|
version "1.5.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/kolorist/-/kolorist-1.5.1.tgz#c3d66dc4fabde4f6b7faa6efda84c00491f9e52b"
|
||||||
|
integrity sha512-lxpCM3HTvquGxKGzHeknB/sUjuVoUElLlfYnXZT73K8geR9jQbroGlSCFBax9/0mpGoD3kzcMLnOlGQPJJNyqQ==
|
||||||
|
|
||||||
|
lower-case@^2.0.2:
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28"
|
||||||
|
integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==
|
||||||
|
dependencies:
|
||||||
|
tslib "^2.0.3"
|
||||||
|
|
||||||
|
magic-string@^0.25.7:
|
||||||
|
version "0.25.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051"
|
||||||
|
integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==
|
||||||
|
dependencies:
|
||||||
|
sourcemap-codec "^1.4.4"
|
||||||
|
|
||||||
|
mdn-data@2.0.14:
|
||||||
|
version "2.0.14"
|
||||||
|
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50"
|
||||||
|
integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==
|
||||||
|
|
||||||
|
merge2@^1.3.0:
|
||||||
|
version "1.4.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
|
||||||
|
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
|
||||||
|
|
||||||
|
micromatch@^4.0.4:
|
||||||
|
version "4.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
|
||||||
|
integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
|
||||||
|
dependencies:
|
||||||
|
braces "^3.0.1"
|
||||||
|
picomatch "^2.2.3"
|
||||||
|
|
||||||
|
min-indent@^1.0.0:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869"
|
||||||
|
integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==
|
||||||
|
|
||||||
|
minimatch@^3.0.4:
|
||||||
|
version "3.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
|
||||||
|
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
|
||||||
|
dependencies:
|
||||||
|
brace-expansion "^1.1.7"
|
||||||
|
|
||||||
|
minimist@^1.2.0, minimist@^1.2.5:
|
||||||
|
version "1.2.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||||
|
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
||||||
|
|
||||||
|
mkdirp@^0.5.1:
|
||||||
|
version "0.5.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
|
||||||
|
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
|
||||||
|
dependencies:
|
||||||
|
minimist "^1.2.5"
|
||||||
|
|
||||||
|
mri@^1.1.0:
|
||||||
|
version "1.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b"
|
||||||
|
integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==
|
||||||
|
|
||||||
|
ms@2.1.2:
|
||||||
|
version "2.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||||
|
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||||
|
|
||||||
|
nanoid@^3.2.0:
|
||||||
|
version "3.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35"
|
||||||
|
integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==
|
||||||
|
|
||||||
|
no-case@^3.0.4:
|
||||||
|
version "3.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d"
|
||||||
|
integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==
|
||||||
|
dependencies:
|
||||||
|
lower-case "^2.0.2"
|
||||||
|
tslib "^2.0.3"
|
||||||
|
|
||||||
|
normalize-path@^3.0.0, normalize-path@~3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
|
||||||
|
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
|
||||||
|
|
||||||
|
nth-check@^2.0.1:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2"
|
||||||
|
integrity sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==
|
||||||
|
dependencies:
|
||||||
|
boolbase "^1.0.0"
|
||||||
|
|
||||||
|
once@^1.3.0:
|
||||||
|
version "1.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||||
|
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
|
||||||
|
dependencies:
|
||||||
|
wrappy "1"
|
||||||
|
|
||||||
|
parent-module@^1.0.0:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
|
||||||
|
integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==
|
||||||
|
dependencies:
|
||||||
|
callsites "^3.0.0"
|
||||||
|
|
||||||
|
pascal-case@^3.1.1:
|
||||||
|
version "3.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb"
|
||||||
|
integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==
|
||||||
|
dependencies:
|
||||||
|
no-case "^3.0.4"
|
||||||
|
tslib "^2.0.3"
|
||||||
|
|
||||||
|
path-is-absolute@^1.0.0:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||||
|
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
|
||||||
|
|
||||||
|
path-parse@^1.0.7:
|
||||||
|
version "1.0.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
|
||||||
|
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
|
||||||
|
|
||||||
|
picocolors@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
|
||||||
|
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
|
||||||
|
|
||||||
|
picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.2.3:
|
||||||
|
version "2.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
|
||||||
|
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
|
||||||
|
|
||||||
|
postcss@^8.4.6:
|
||||||
|
version "8.4.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.6.tgz#c5ff3c3c457a23864f32cb45ac9b741498a09ae1"
|
||||||
|
integrity sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA==
|
||||||
|
dependencies:
|
||||||
|
nanoid "^3.2.0"
|
||||||
|
picocolors "^1.0.0"
|
||||||
|
source-map-js "^1.0.2"
|
||||||
|
|
||||||
|
prettier-plugin-svelte@^2.6.0:
|
||||||
|
version "2.6.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/prettier-plugin-svelte/-/prettier-plugin-svelte-2.6.0.tgz#0e845b560b55cd1d951d6c50431b4949f8591746"
|
||||||
|
integrity sha512-NPSRf6Y5rufRlBleok/pqg4+1FyGsL0zYhkYP6hnueeL1J/uCm3OfOZPsLX4zqD9VAdcXfyEL2PYqGv8ZoOSfA==
|
||||||
|
|
||||||
|
prettier@^2.5.1:
|
||||||
|
version "2.5.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a"
|
||||||
|
integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==
|
||||||
|
|
||||||
|
queue-microtask@^1.2.2:
|
||||||
|
version "1.2.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
||||||
|
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
|
||||||
|
|
||||||
|
readdirp@~3.6.0:
|
||||||
|
version "3.6.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
|
||||||
|
integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
|
||||||
|
dependencies:
|
||||||
|
picomatch "^2.2.1"
|
||||||
|
|
||||||
|
resolve-from@^4.0.0:
|
||||||
|
version "4.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
|
||||||
|
integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
|
||||||
|
|
||||||
|
resolve@^1.22.0:
|
||||||
|
version "1.22.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198"
|
||||||
|
integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==
|
||||||
|
dependencies:
|
||||||
|
is-core-module "^2.8.1"
|
||||||
|
path-parse "^1.0.7"
|
||||||
|
supports-preserve-symlinks-flag "^1.0.0"
|
||||||
|
|
||||||
|
reusify@^1.0.4:
|
||||||
|
version "1.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
|
||||||
|
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
|
||||||
|
|
||||||
|
rimraf@^2.5.2:
|
||||||
|
version "2.7.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
|
||||||
|
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
|
||||||
|
dependencies:
|
||||||
|
glob "^7.1.3"
|
||||||
|
|
||||||
|
rollup-plugin-svelte-svg@^1.0.0-beta.6:
|
||||||
|
version "1.0.0-beta.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/rollup-plugin-svelte-svg/-/rollup-plugin-svelte-svg-1.0.0-beta.6.tgz#0ee3deae2329abb1c90f50b83598aaf0bb0559fc"
|
||||||
|
integrity sha512-6uJb9kuaqK6p+DvkgphhGN18wvUzdT6h7MQC2B8P1omi9omC9lQC54pwaot21h6z9ibhGPLG9a1XFLeDQth/kg==
|
||||||
|
dependencies:
|
||||||
|
rollup-pluginutils "^2.8.2"
|
||||||
|
svgo "^2.3.1"
|
||||||
|
|
||||||
|
rollup-pluginutils@^2.8.2:
|
||||||
|
version "2.8.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e"
|
||||||
|
integrity sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==
|
||||||
|
dependencies:
|
||||||
|
estree-walker "^0.6.1"
|
||||||
|
|
||||||
|
rollup@^2.59.0:
|
||||||
|
version "2.67.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.67.3.tgz#3f04391fc296f807d067c9081d173e0a33dbd37e"
|
||||||
|
integrity sha512-G/x1vUwbGtP6O5ZM8/sWr8+p7YfZhI18pPqMRtMYMWSbHjKZ/ajHGiM+GWNTlWyOR0EHIdT8LHU+Z4ciIZ1oBw==
|
||||||
|
optionalDependencies:
|
||||||
|
fsevents "~2.3.2"
|
||||||
|
|
||||||
|
run-parallel@^1.1.9:
|
||||||
|
version "1.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee"
|
||||||
|
integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==
|
||||||
|
dependencies:
|
||||||
|
queue-microtask "^1.2.2"
|
||||||
|
|
||||||
|
sade@^1.7.4:
|
||||||
|
version "1.8.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/sade/-/sade-1.8.1.tgz#0a78e81d658d394887be57d2a409bf703a3b2701"
|
||||||
|
integrity sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==
|
||||||
|
dependencies:
|
||||||
|
mri "^1.1.0"
|
||||||
|
|
||||||
|
sander@^0.5.0:
|
||||||
|
version "0.5.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/sander/-/sander-0.5.1.tgz#741e245e231f07cafb6fdf0f133adfa216a502ad"
|
||||||
|
integrity sha1-dB4kXiMfB8r7b98PEzrfohalAq0=
|
||||||
|
dependencies:
|
||||||
|
es6-promise "^3.1.2"
|
||||||
|
graceful-fs "^4.1.3"
|
||||||
|
mkdirp "^0.5.1"
|
||||||
|
rimraf "^2.5.2"
|
||||||
|
|
||||||
|
sorcery@^0.10.0:
|
||||||
|
version "0.10.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/sorcery/-/sorcery-0.10.0.tgz#8ae90ad7d7cb05fc59f1ab0c637845d5c15a52b7"
|
||||||
|
integrity sha1-iukK19fLBfxZ8asMY3hF1cFaUrc=
|
||||||
|
dependencies:
|
||||||
|
buffer-crc32 "^0.2.5"
|
||||||
|
minimist "^1.2.0"
|
||||||
|
sander "^0.5.0"
|
||||||
|
sourcemap-codec "^1.3.0"
|
||||||
|
|
||||||
|
source-map-js@^1.0.2:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
|
||||||
|
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
|
||||||
|
|
||||||
|
source-map@^0.6.1:
|
||||||
|
version "0.6.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
||||||
|
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
|
||||||
|
|
||||||
|
source-map@^0.7.3:
|
||||||
|
version "0.7.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
|
||||||
|
integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==
|
||||||
|
|
||||||
|
sourcemap-codec@^1.3.0, sourcemap-codec@^1.4.4:
|
||||||
|
version "1.4.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4"
|
||||||
|
integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==
|
||||||
|
|
||||||
|
stable@^0.1.8:
|
||||||
|
version "0.1.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf"
|
||||||
|
integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==
|
||||||
|
|
||||||
|
strip-indent@^3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001"
|
||||||
|
integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==
|
||||||
|
dependencies:
|
||||||
|
min-indent "^1.0.0"
|
||||||
|
|
||||||
|
supports-preserve-symlinks-flag@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
|
||||||
|
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
|
||||||
|
|
||||||
|
svelte-check@^2.2.7:
|
||||||
|
version "2.4.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/svelte-check/-/svelte-check-2.4.5.tgz#a2001993034d495118980bd95577fb3e7980661a"
|
||||||
|
integrity sha512-nRft8BbG2wcxyCdHDZ7X43xLcvDzua3xLwq6wzHGcAF3ka3Jyhv2rvgq0+SF9NwHLMefp9C2XkM6etzsxK/cMQ==
|
||||||
|
dependencies:
|
||||||
|
chokidar "^3.4.1"
|
||||||
|
fast-glob "^3.2.7"
|
||||||
|
import-fresh "^3.2.1"
|
||||||
|
minimist "^1.2.5"
|
||||||
|
picocolors "^1.0.0"
|
||||||
|
sade "^1.7.4"
|
||||||
|
source-map "^0.7.3"
|
||||||
|
svelte-preprocess "^4.0.0"
|
||||||
|
typescript "*"
|
||||||
|
|
||||||
|
svelte-hmr@^0.14.9:
|
||||||
|
version "0.14.9"
|
||||||
|
resolved "https://registry.yarnpkg.com/svelte-hmr/-/svelte-hmr-0.14.9.tgz#35f277efc789e1a6230185717347cddb2f8e9833"
|
||||||
|
integrity sha512-bKE9+4qb4sAnA+TKHiYurUl970rjA0XmlP9TEP7K/ncyWz3m81kA4HOgmlZK/7irGK7gzZlaPDI3cmf8fp/+tg==
|
||||||
|
|
||||||
|
svelte-navigator@^3.1.5:
|
||||||
|
version "3.1.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/svelte-navigator/-/svelte-navigator-3.1.5.tgz#f79d78b2c2c5ad907d8b1d3748d3fbe12c32195c"
|
||||||
|
integrity sha512-CGTaexasSLpUaTSN2AlYqii0JeisIgg7uZbm8XCLKlpM9Qv3IltlJ7Nvh90Xw9ND97KqtGOjNJ3LNwMN1ABV0w==
|
||||||
|
dependencies:
|
||||||
|
svelte2tsx "^0.1.151"
|
||||||
|
|
||||||
|
svelte-preprocess@^4.0.0, svelte-preprocess@^4.9.8:
|
||||||
|
version "4.10.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/svelte-preprocess/-/svelte-preprocess-4.10.3.tgz#9aac89a8abc3889fa5740fb34f7dd74f3c578e13"
|
||||||
|
integrity sha512-ttw17lJfb/dx2ZJT9sesaXT5l7mPQ9Apx1H496Kli3Hkk7orIRGpOw6rCPkRNzr6ueVPqb4vzodS5x7sBFhKHw==
|
||||||
|
dependencies:
|
||||||
|
"@types/pug" "^2.0.4"
|
||||||
|
"@types/sass" "^1.16.0"
|
||||||
|
detect-indent "^6.0.0"
|
||||||
|
magic-string "^0.25.7"
|
||||||
|
sorcery "^0.10.0"
|
||||||
|
strip-indent "^3.0.0"
|
||||||
|
|
||||||
|
svelte2tsx@^0.1.151:
|
||||||
|
version "0.1.193"
|
||||||
|
resolved "https://registry.yarnpkg.com/svelte2tsx/-/svelte2tsx-0.1.193.tgz#16fe594898ef455e4f715ac317d219c9c757656b"
|
||||||
|
integrity sha512-vzy4YQNYDnoqp2iZPnJy7kpPAY6y121L0HKrSBjU/IWW7DQ6T7RMJed2VVHFmVYm0zAGYMDl9urPc6R4DDUyhg==
|
||||||
|
dependencies:
|
||||||
|
dedent-js "^1.0.1"
|
||||||
|
pascal-case "^3.1.1"
|
||||||
|
|
||||||
|
svelte@^3.44.0:
|
||||||
|
version "3.46.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.46.4.tgz#0c46bc4a3e20a2617a1b7dc43a722f9d6c084a38"
|
||||||
|
integrity sha512-qKJzw6DpA33CIa+C/rGp4AUdSfii0DOTCzj/2YpSKKayw5WGSS624Et9L1nU1k2OVRS9vaENQXp2CVZNU+xvIg==
|
||||||
|
|
||||||
|
svgo@^2.3.1:
|
||||||
|
version "2.8.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24"
|
||||||
|
integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==
|
||||||
|
dependencies:
|
||||||
|
"@trysound/sax" "0.2.0"
|
||||||
|
commander "^7.2.0"
|
||||||
|
css-select "^4.1.3"
|
||||||
|
css-tree "^1.1.3"
|
||||||
|
csso "^4.2.0"
|
||||||
|
picocolors "^1.0.0"
|
||||||
|
stable "^0.1.8"
|
||||||
|
|
||||||
|
to-regex-range@^5.0.1:
|
||||||
|
version "5.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
|
||||||
|
integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
|
||||||
|
dependencies:
|
||||||
|
is-number "^7.0.0"
|
||||||
|
|
||||||
|
tslib@^2.0.3, tslib@^2.3.1:
|
||||||
|
version "2.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01"
|
||||||
|
integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==
|
||||||
|
|
||||||
|
typescript@*, typescript@^4.5.4:
|
||||||
|
version "4.5.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.5.tgz#d8c953832d28924a9e3d37c73d729c846c5896f3"
|
||||||
|
integrity sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==
|
||||||
|
|
||||||
|
vite-plugin-windicss@^1.7.1:
|
||||||
|
version "1.7.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/vite-plugin-windicss/-/vite-plugin-windicss-1.7.1.tgz#23fadfcb400bd0d7e991d0264f547f499bd57ddc"
|
||||||
|
integrity sha512-eEDeTPaeQAfe0widkTkm9X51BVpOE/yDIuFbULIKjXI7CfY1yjsPcxA6E3aZbLBYQcUmfhVUTYVaH5iAE5L8Hg==
|
||||||
|
dependencies:
|
||||||
|
"@windicss/plugin-utils" "1.7.1"
|
||||||
|
debug "^4.3.3"
|
||||||
|
kolorist "^1.5.1"
|
||||||
|
windicss "^3.4.3"
|
||||||
|
|
||||||
|
vite@^2.8.0:
|
||||||
|
version "2.8.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/vite/-/vite-2.8.4.tgz#4e52a534289b7b4e94e646df2fc5556ceaa7336b"
|
||||||
|
integrity sha512-GwtOkkaT2LDI82uWZKcrpRQxP5tymLnC7hVHHqNkhFNknYr0hJUlDLfhVRgngJvAy3RwypkDCWtTKn1BjO96Dw==
|
||||||
|
dependencies:
|
||||||
|
esbuild "^0.14.14"
|
||||||
|
postcss "^8.4.6"
|
||||||
|
resolve "^1.22.0"
|
||||||
|
rollup "^2.59.0"
|
||||||
|
optionalDependencies:
|
||||||
|
fsevents "~2.3.2"
|
||||||
|
|
||||||
|
windicss@^3.4.3:
|
||||||
|
version "3.4.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/windicss/-/windicss-3.4.3.tgz#347d09fee8eb6b3fc5e6e68b435c76ccb24a748c"
|
||||||
|
integrity sha512-UnugThsvEgy8RsPm4/B5DYMCAqvZzD6yWU7Anh+f07t5RSJ8zvmAylGLbXrHPJEmCKzo2Mf+fOUvISH7IJqM3A==
|
||||||
|
|
||||||
|
wrappy@1:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||||
|
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
@ -9,10 +9,7 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: ./
|
context: ./
|
||||||
dockerfile: front/Dockerfile
|
dockerfile: front/Dockerfile
|
||||||
environment:
|
command: /bin/sh -c "/templater.sh && envsubst < /usr/share/nginx/html/env-config.template.js > /usr/share/nginx/html/env-config.js && exec nginx -g 'daemon off;'"
|
||||||
STARTUP_COMMAND_1: 'envsubst < dist/env-config.template.js > dist/env-config.js'
|
|
||||||
STARTUP_COMMAND_2: ''
|
|
||||||
command: apache2-foreground
|
|
||||||
volumes: []
|
volumes: []
|
||||||
labels:
|
labels:
|
||||||
- "traefik.enable=true"
|
- "traefik.enable=true"
|
||||||
@ -29,19 +26,15 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: ./
|
context: ./
|
||||||
dockerfile: pusher/Dockerfile
|
dockerfile: pusher/Dockerfile
|
||||||
environment:
|
|
||||||
STARTUP_COMMAND_1: ''
|
|
||||||
STARTUP_COMMAND_2: ''
|
|
||||||
command: yarn run runprod
|
command: yarn run runprod
|
||||||
volumes: []
|
volumes: []
|
||||||
|
environment:
|
||||||
|
ENABLE_OPENAPI_ENDPOINT: "false"
|
||||||
|
|
||||||
back:
|
back:
|
||||||
image: 'wa-back-e2e'
|
image: 'wa-back-e2e'
|
||||||
build:
|
build:
|
||||||
context: ./
|
context: ./
|
||||||
dockerfile: back/Dockerfile
|
dockerfile: back/Dockerfile
|
||||||
environment:
|
|
||||||
STARTUP_COMMAND_1: ''
|
|
||||||
STARTUP_COMMAND_2: ''
|
|
||||||
command: yarn run runprod
|
command: yarn run runprod
|
||||||
volumes: []
|
volumes: []
|
||||||
|
@ -76,6 +76,9 @@ services:
|
|||||||
OPID_CLIENT_ISSUER: $OPID_CLIENT_ISSUER
|
OPID_CLIENT_ISSUER: $OPID_CLIENT_ISSUER
|
||||||
OPID_CLIENT_REDIRECT_URL: $OPID_CLIENT_REDIRECT_URL
|
OPID_CLIENT_REDIRECT_URL: $OPID_CLIENT_REDIRECT_URL
|
||||||
OPID_PROFILE_SCREEN_PROVIDER: $OPID_PROFILE_SCREEN_PROVIDER
|
OPID_PROFILE_SCREEN_PROVIDER: $OPID_PROFILE_SCREEN_PROVIDER
|
||||||
|
OPID_SCOPE: $OPID_SCOPE
|
||||||
|
OPID_USERNAME_CLAIM: $OPID_USERNAME_CLAIM
|
||||||
|
OPID_LOCALE_CLAIM: $OPID_LOCALE_CLAIM
|
||||||
DISABLE_ANONYMOUS: $DISABLE_ANONYMOUS
|
DISABLE_ANONYMOUS: $DISABLE_ANONYMOUS
|
||||||
volumes:
|
volumes:
|
||||||
- ./pusher:/usr/src/app
|
- ./pusher:/usr/src/app
|
||||||
|
@ -85,6 +85,9 @@ services:
|
|||||||
OPID_CLIENT_ISSUER: $OPID_CLIENT_ISSUER
|
OPID_CLIENT_ISSUER: $OPID_CLIENT_ISSUER
|
||||||
OPID_CLIENT_REDIRECT_URL: $OPID_CLIENT_REDIRECT_URL
|
OPID_CLIENT_REDIRECT_URL: $OPID_CLIENT_REDIRECT_URL
|
||||||
OPID_PROFILE_SCREEN_PROVIDER: $OPID_PROFILE_SCREEN_PROVIDER
|
OPID_PROFILE_SCREEN_PROVIDER: $OPID_PROFILE_SCREEN_PROVIDER
|
||||||
|
OPID_SCOPE: $OPID_SCOPE
|
||||||
|
OPID_USERNAME_CLAIM: $OPID_USERNAME_CLAIM
|
||||||
|
OPID_LOCALE_CLAIM: $OPID_LOCALE_CLAIM
|
||||||
DISABLE_ANONYMOUS: $DISABLE_ANONYMOUS
|
DISABLE_ANONYMOUS: $DISABLE_ANONYMOUS
|
||||||
ENABLE_OPENAPI_ENDPOINT: "true"
|
ENABLE_OPENAPI_ENDPOINT: "true"
|
||||||
volumes:
|
volumes:
|
||||||
|
@ -13,6 +13,8 @@ In order to create Jitsi meet zones:
|
|||||||
* In layer properties, you MUST add a "`jitsiRoom`" property (of type "`string`"). The value of the property is the name of the room in Jitsi. Note: the name of the room will be "slugified" and prepended with the name of the instance of the map (so that different instances of the map have different rooms)
|
* In layer properties, you MUST add a "`jitsiRoom`" property (of type "`string`"). The value of the property is the name of the room in Jitsi. Note: the name of the room will be "slugified" and prepended with the name of the instance of the map (so that different instances of the map have different rooms)
|
||||||
* You may also use "jitsiWidth" property (of type "number" between 0 and 100) to control the width of the iframe containing the meeting room.
|
* You may also use "jitsiWidth" property (of type "number" between 0 and 100) to control the width of the iframe containing the meeting room.
|
||||||
|
|
||||||
|
You can have this layer (i.e. your meeting area) to be selectable as the precise location for your meeting using the [Google Calendar integration for Work Adventure](/integrations/google-calendar). To do so, you must set the `meetingRoomLabel` property. You can provide any name that you would like your meeting room to have (as a string).
|
||||||
|
|
||||||
## Triggering of the "Jitsi meet" action
|
## Triggering of the "Jitsi meet" action
|
||||||
|
|
||||||
By default, Jitsi meet will open when a user enters the zone defined on the map.
|
By default, Jitsi meet will open when a user enters the zone defined on the map.
|
||||||
|
@ -1,31 +1,33 @@
|
|||||||
|
# The building of ProtoBuf "messages" must be done out of Docker because grpc-node does not ship with ARM64 binaries.
|
||||||
|
# See: https://github.com/grpc/grpc-node/issues/1405
|
||||||
|
# When the issue above is closed, we can move back messages building inside Dockerfile
|
||||||
|
|
||||||
|
# protobuf build
|
||||||
|
#FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as proto-builder
|
||||||
|
#WORKDIR /usr/src
|
||||||
|
#COPY messages/yarn.lock messages/package.json ./
|
||||||
|
#RUN yarn install
|
||||||
|
#COPY messages .
|
||||||
|
#RUN yarn ts-proto
|
||||||
|
|
||||||
|
# typescript build
|
||||||
FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as builder
|
FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as builder
|
||||||
|
WORKDIR /usr/src
|
||||||
WORKDIR /usr/src/messages
|
COPY front/yarn.lock front/package.json ./
|
||||||
COPY messages .
|
RUN yarn install --network-timeout 1000000
|
||||||
RUN yarn install && yarn ts-proto
|
|
||||||
|
|
||||||
WORKDIR /usr/src/front
|
|
||||||
COPY front .
|
COPY front .
|
||||||
|
#COPY --from=proto-builder /usr/src/ts-proto-generated/protos src/Messages/ts-proto-generated
|
||||||
|
#RUN sed -i 's/import { Observable } from "rxjs";/import type { Observable } from "rxjs";/g' src/Messages/ts-proto-generated/messages.ts
|
||||||
|
#COPY --from=proto-builder /usr/src/JsonMessages src/Messages/JsonMessages
|
||||||
|
RUN yarn run typesafe-i18n && yarn run build-iframe-api && yarn build
|
||||||
|
|
||||||
# move messages to front
|
# final production image
|
||||||
RUN cp -r ../messages/ts-proto-generated/protos/* src/Messages/ts-proto-generated
|
FROM nginx:1.21.6-alpine
|
||||||
RUN sed -i 's/import { Observable } from "rxjs";/import type { Observable } from "rxjs";/g' src/Messages/ts-proto-generated/messages.ts
|
|
||||||
RUN cp -r ../messages/JsonMessages/* src/Messages/JsonMessages
|
|
||||||
|
|
||||||
RUN yarn install && yarn run typesafe-i18n && yarn run build-iframe-api && yarn build
|
COPY front/nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
|
COPY front/templater.sh /
|
||||||
|
|
||||||
FROM thecodingmachine/nodejs:14-apache
|
COPY --from=builder /usr/src/dist /usr/share/nginx/html
|
||||||
|
|
||||||
COPY --from=builder --chown=docker:docker /usr/src/front/dist dist
|
EXPOSE 80
|
||||||
COPY front/templater.sh .
|
CMD ["/bin/sh", "-c", "/templater.sh && envsubst < /usr/share/nginx/html/env-config.template.js > /usr/share/nginx/html/env-config.js && exec nginx -g 'daemon off;'"]
|
||||||
|
|
||||||
USER root
|
|
||||||
RUN DEBIAN_FRONTEND=noninteractive apt-get update \
|
|
||||||
&& apt-get install -y \
|
|
||||||
gettext-base \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
|
||||||
USER docker
|
|
||||||
|
|
||||||
ENV STARTUP_COMMAND_0="./templater.sh"
|
|
||||||
ENV STARTUP_COMMAND_1="envsubst < dist/env-config.template.js > dist/env-config.js"
|
|
||||||
ENV APACHE_DOCUMENT_ROOT=dist/
|
|
||||||
|
51
front/nginx.conf
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
server_name localhost;
|
||||||
|
access_log off;
|
||||||
|
|
||||||
|
gzip on;
|
||||||
|
gzip_comp_level 6;
|
||||||
|
gzip_min_length 1000;
|
||||||
|
gzip_proxied any;
|
||||||
|
gzip_disable "msie6";
|
||||||
|
gzip_types
|
||||||
|
application/atom+xml
|
||||||
|
application/geo+json
|
||||||
|
application/javascript
|
||||||
|
application/x-javascript
|
||||||
|
application/json
|
||||||
|
application/ld+json
|
||||||
|
application/manifest+json
|
||||||
|
application/rdf+xml
|
||||||
|
application/rss+xml
|
||||||
|
application/xhtml+xml
|
||||||
|
application/xml
|
||||||
|
font/eot
|
||||||
|
font/otf
|
||||||
|
font/ttf
|
||||||
|
image/svg+xml
|
||||||
|
text/css
|
||||||
|
text/javascript
|
||||||
|
text/plain
|
||||||
|
text/xml;
|
||||||
|
|
||||||
|
# serve static assets (that have a cache busting hash) with an efficient cache policy
|
||||||
|
location /assets {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
expires 1y;
|
||||||
|
add_header Cache-Control "public";
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html;
|
||||||
|
rewrite ^/register/ /index.html break;
|
||||||
|
rewrite ^/login /index.html break;
|
||||||
|
rewrite ^/jwt /index.html break;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ ^/[@_]/ {
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
}
|
38
front/src/Api/desktop/index.ts
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import { isSilentStore, requestedCameraState, requestedMicrophoneState } from "../../Stores/MediaStore";
|
||||||
|
import { get } from "svelte/store";
|
||||||
|
|
||||||
|
class DesktopApi {
|
||||||
|
isSilent: boolean = false;
|
||||||
|
|
||||||
|
init() {
|
||||||
|
if (!window?.WAD?.desktop) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Yipee you are using the desktop app ;)");
|
||||||
|
|
||||||
|
window.WAD.onMuteToggle(() => {
|
||||||
|
if (this.isSilent) return;
|
||||||
|
if (get(requestedMicrophoneState) === true) {
|
||||||
|
requestedMicrophoneState.disableMicrophone();
|
||||||
|
} else {
|
||||||
|
requestedMicrophoneState.enableMicrophone();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
window.WAD.onCameraToggle(() => {
|
||||||
|
if (this.isSilent) return;
|
||||||
|
if (get(requestedCameraState) === true) {
|
||||||
|
requestedCameraState.disableWebcam();
|
||||||
|
} else {
|
||||||
|
requestedCameraState.enableWebcam();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
isSilentStore.subscribe((value) => {
|
||||||
|
this.isSilent = value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const desktopApi = new DesktopApi();
|
21
front/src/Components/Lazy.svelte
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<!-- https://lihautan.com/notes/svelte-lazy-load/ -->
|
||||||
|
<script>
|
||||||
|
export let when = false;
|
||||||
|
export let component;
|
||||||
|
|
||||||
|
let loading;
|
||||||
|
|
||||||
|
$: if (when) {
|
||||||
|
load();
|
||||||
|
}
|
||||||
|
|
||||||
|
function load() {
|
||||||
|
loading = component();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if when}
|
||||||
|
{#await loading then { default: Component }}
|
||||||
|
<Component />
|
||||||
|
{/await}
|
||||||
|
{/if}
|
@ -12,7 +12,6 @@
|
|||||||
import AudioManager from "./AudioManager/AudioManager.svelte";
|
import AudioManager from "./AudioManager/AudioManager.svelte";
|
||||||
import CameraControls from "./CameraControls.svelte";
|
import CameraControls from "./CameraControls.svelte";
|
||||||
import EmbedScreensContainer from "./EmbedScreens/EmbedScreensContainer.svelte";
|
import EmbedScreensContainer from "./EmbedScreens/EmbedScreensContainer.svelte";
|
||||||
import EmoteMenu from "./EmoteMenu/EmoteMenu.svelte";
|
|
||||||
import HelpCameraSettingsPopup from "./HelpCameraSettings/HelpCameraSettingsPopup.svelte";
|
import HelpCameraSettingsPopup from "./HelpCameraSettings/HelpCameraSettingsPopup.svelte";
|
||||||
import LayoutActionManager from "./LayoutActionManager/LayoutActionManager.svelte";
|
import LayoutActionManager from "./LayoutActionManager/LayoutActionManager.svelte";
|
||||||
import Menu from "./Menu/Menu.svelte";
|
import Menu from "./Menu/Menu.svelte";
|
||||||
@ -38,6 +37,7 @@
|
|||||||
import { LayoutMode } from "../WebRtc/LayoutManager";
|
import { LayoutMode } from "../WebRtc/LayoutManager";
|
||||||
import { actionsMenuStore } from "../Stores/ActionsMenuStore";
|
import { actionsMenuStore } from "../Stores/ActionsMenuStore";
|
||||||
import ActionsMenu from "./ActionsMenu/ActionsMenu.svelte";
|
import ActionsMenu from "./ActionsMenu/ActionsMenu.svelte";
|
||||||
|
import Lazy from "./Lazy.svelte";
|
||||||
|
|
||||||
let mainLayout: HTMLDivElement;
|
let mainLayout: HTMLDivElement;
|
||||||
|
|
||||||
@ -116,9 +116,7 @@
|
|||||||
<VisitCard visitCardUrl={$requestVisitCardsStore} />
|
<VisitCard visitCardUrl={$requestVisitCardsStore} />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if $emoteMenuStore}
|
<Lazy when={$emoteMenuStore} component={() => import("./EmoteMenu/EmoteMenu.svelte")} />
|
||||||
<EmoteMenu />
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{#if hasEmbedScreen}
|
{#if hasEmbedScreen}
|
||||||
<EmbedScreensContainer />
|
<EmbedScreensContainer />
|
||||||
|
@ -16,6 +16,10 @@ import { isRegisterData } from "../Messages/JsonMessages/RegisterData";
|
|||||||
import { isAdminApiData } from "../Messages/JsonMessages/AdminApiData";
|
import { isAdminApiData } from "../Messages/JsonMessages/AdminApiData";
|
||||||
import { limitMapStore } from "../Stores/GameStore";
|
import { limitMapStore } from "../Stores/GameStore";
|
||||||
import { showLimitRoomModalStore } from "../Stores/ModalStore";
|
import { showLimitRoomModalStore } from "../Stores/ModalStore";
|
||||||
|
import { gameManager } from "../Phaser/Game/GameManager";
|
||||||
|
import { locales } from "../i18n/i18n-util";
|
||||||
|
import type { Locales } from "../i18n/i18n-types";
|
||||||
|
import { setCurrentLocale } from "../i18n/locales";
|
||||||
|
|
||||||
class ConnectionManager {
|
class ConnectionManager {
|
||||||
private localUser!: LocalUser;
|
private localUser!: LocalUser;
|
||||||
@ -326,7 +330,7 @@ class ConnectionManager {
|
|||||||
throw new Error("No Auth code provided");
|
throw new Error("No Auth code provided");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const { authToken, userUuid, email } = await Axios.get(`${PUSHER_URL}/login-callback`, {
|
const { authToken, userUuid, email, username, locale } = await Axios.get(`${PUSHER_URL}/login-callback`, {
|
||||||
params: { code, nonce, token, playUri: this.currentRoom?.key },
|
params: { code, nonce, token, playUri: this.currentRoom?.key },
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
return res.data;
|
return res.data;
|
||||||
@ -336,6 +340,27 @@ class ConnectionManager {
|
|||||||
localUserStore.saveUser(this.localUser);
|
localUserStore.saveUser(this.localUser);
|
||||||
this.authToken = authToken;
|
this.authToken = authToken;
|
||||||
|
|
||||||
|
if (username) {
|
||||||
|
gameManager.setPlayerName(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (locale) {
|
||||||
|
try {
|
||||||
|
if (locales.indexOf(locale) == -1) {
|
||||||
|
locales.forEach((l) => {
|
||||||
|
if (l.startsWith(locale.split("-")[0])) {
|
||||||
|
setCurrentLocale(l);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setCurrentLocale(locale as Locales);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.warn("Could not set locale", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//user connected, set connected store for menu at true
|
//user connected, set connected store for menu at true
|
||||||
userIsConnected.set(true);
|
userIsConnected.set(true);
|
||||||
}
|
}
|
||||||
|
@ -126,19 +126,7 @@ export class GameMap {
|
|||||||
for (let y = 0; y < this.map.height; y += 1) {
|
for (let y = 0; y < this.map.height; y += 1) {
|
||||||
const row: number[] = [];
|
const row: number[] = [];
|
||||||
for (let x = 0; x < this.map.width; x += 1) {
|
for (let x = 0; x < this.map.width; x += 1) {
|
||||||
row.push(this.isCollidingAt(x, y) ? 1 : 0);
|
row.push(this.isCollidingAt(x, y) ? 1 : this.isExitTile(x, y) ? 2 : 0);
|
||||||
}
|
|
||||||
grid.push(row);
|
|
||||||
}
|
|
||||||
return grid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getWalkingCostGrid(): number[][] {
|
|
||||||
const grid: number[][] = [];
|
|
||||||
for (let y = 0; y < this.map.height; y += 1) {
|
|
||||||
const row: number[] = [];
|
|
||||||
for (let x = 0; x < this.map.width; x += 1) {
|
|
||||||
row.push(this.getWalkingCostAt(x, y));
|
|
||||||
}
|
}
|
||||||
grid.push(row);
|
grid.push(row);
|
||||||
}
|
}
|
||||||
@ -355,8 +343,7 @@ export class GameMap {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getWalkingCostAt(x: number, y: number): number {
|
private isExitTile(x: number, y: number): boolean {
|
||||||
const bigCost = 100;
|
|
||||||
for (const layer of this.phaserLayers) {
|
for (const layer of this.phaserLayers) {
|
||||||
if (!layer.visible) {
|
if (!layer.visible) {
|
||||||
continue;
|
continue;
|
||||||
@ -369,16 +356,16 @@ export class GameMap {
|
|||||||
tile &&
|
tile &&
|
||||||
(tile.properties[GameMapProperties.EXIT_URL] || tile.properties[GameMapProperties.EXIT_SCENE_URL])
|
(tile.properties[GameMapProperties.EXIT_URL] || tile.properties[GameMapProperties.EXIT_SCENE_URL])
|
||||||
) {
|
) {
|
||||||
return bigCost;
|
return true;
|
||||||
}
|
}
|
||||||
for (const property of layer.layer.properties) {
|
for (const property of layer.layer.properties) {
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
if (property.name && property.name === "exitUrl") {
|
if (property.name && property.name === "exitUrl") {
|
||||||
return bigCost;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private triggerAllProperties(): void {
|
private triggerAllProperties(): void {
|
||||||
|
@ -566,7 +566,6 @@ export class GameScene extends DirtyScene {
|
|||||||
this.pathfindingManager = new PathfindingManager(
|
this.pathfindingManager = new PathfindingManager(
|
||||||
this,
|
this,
|
||||||
this.gameMap.getCollisionGrid(),
|
this.gameMap.getCollisionGrid(),
|
||||||
this.gameMap.getWalkingCostGrid(),
|
|
||||||
this.gameMap.getTileDimensions()
|
this.gameMap.getTileDimensions()
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1453,7 +1452,7 @@ ${escapedMessage}
|
|||||||
phaserLayers[i].setCollisionByProperty({ collides: true }, visible);
|
phaserLayers[i].setCollisionByProperty({ collides: true }, visible);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.pathfindingManager.setCollisionGrid(this.gameMap.getCollisionGrid(), this.gameMap.getWalkingCostGrid());
|
this.pathfindingManager.setCollisionGrid(this.gameMap.getCollisionGrid());
|
||||||
this.markDirty();
|
this.markDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1601,6 +1600,8 @@ ${escapedMessage}
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((reason) => console.warn(reason));
|
.catch((reason) => console.warn(reason));
|
||||||
|
|
||||||
|
urlManager.clearHashParameter();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn(`Cannot proceed with moveTo command:\n\t-> ${err}`);
|
console.warn(`Cannot proceed with moveTo command:\n\t-> ${err}`);
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,10 @@ class UrlManager {
|
|||||||
return this.getHashParameters()[name];
|
return this.getHashParameters()[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public clearHashParameter(): void {
|
||||||
|
window.location.hash = "";
|
||||||
|
}
|
||||||
|
|
||||||
private getHashParameters(): Record<string, string> {
|
private getHashParameters(): Record<string, string> {
|
||||||
return window.location.hash
|
return window.location.hash
|
||||||
.substring(1)
|
.substring(1)
|
||||||
|
@ -8,27 +8,21 @@ export class PathfindingManager {
|
|||||||
private grid: number[][];
|
private grid: number[][];
|
||||||
private tileDimensions: { width: number; height: number };
|
private tileDimensions: { width: number; height: number };
|
||||||
|
|
||||||
constructor(
|
constructor(scene: Phaser.Scene, collisionsGrid: number[][], tileDimensions: { width: number; height: number }) {
|
||||||
scene: Phaser.Scene,
|
|
||||||
collisionsGrid: number[][],
|
|
||||||
walkingCostGrid: number[][],
|
|
||||||
tileDimensions: { width: number; height: number }
|
|
||||||
) {
|
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
|
|
||||||
this.easyStar = new EasyStar.js();
|
this.easyStar = new EasyStar.js();
|
||||||
this.easyStar.enableDiagonals();
|
this.easyStar.enableDiagonals();
|
||||||
this.easyStar.disableCornerCutting();
|
this.easyStar.disableCornerCutting();
|
||||||
|
this.easyStar.setTileCost(2, 100);
|
||||||
|
|
||||||
this.grid = collisionsGrid;
|
this.grid = collisionsGrid;
|
||||||
this.tileDimensions = tileDimensions;
|
this.tileDimensions = tileDimensions;
|
||||||
this.setEasyStarGrid(collisionsGrid);
|
this.setEasyStarGrid(collisionsGrid);
|
||||||
this.setWalkingCostGrid(walkingCostGrid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public setCollisionGrid(collisionGrid: number[][], walkingCostGrid: number[][]): void {
|
public setCollisionGrid(collisionGrid: number[][]): void {
|
||||||
this.setEasyStarGrid(collisionGrid);
|
this.setEasyStarGrid(collisionGrid);
|
||||||
this.setWalkingCostGrid(walkingCostGrid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async findPath(
|
public async findPath(
|
||||||
@ -120,15 +114,7 @@ export class PathfindingManager {
|
|||||||
|
|
||||||
private setEasyStarGrid(grid: number[][]): void {
|
private setEasyStarGrid(grid: number[][]): void {
|
||||||
this.easyStar.setGrid(grid);
|
this.easyStar.setGrid(grid);
|
||||||
this.easyStar.setAcceptableTiles([0]); // zeroes are walkable
|
this.easyStar.setAcceptableTiles([0, 2]); // zeroes are walkable, 2 are exits, also walkable
|
||||||
}
|
|
||||||
|
|
||||||
private setWalkingCostGrid(grid: number[][]): void {
|
|
||||||
for (let y = 0; y < grid.length; y += 1) {
|
|
||||||
for (let x = 0; x < grid[y].length; x += 1) {
|
|
||||||
this.easyStar.setAdditionalPointCost(x, y, grid[y][x]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private logGridToTheConsole(grid: number[][]): void {
|
private logGridToTheConsole(grid: number[][]): void {
|
||||||
|
@ -21,6 +21,7 @@ import type { Popup } from "./Api/iframe/Ui/Popup";
|
|||||||
import type { Sound } from "./Api/iframe/Sound/Sound";
|
import type { Sound } from "./Api/iframe/Sound/Sound";
|
||||||
import { answerPromises, queryWorkadventure } from "./Api/iframe/IframeApiContribution";
|
import { answerPromises, queryWorkadventure } from "./Api/iframe/IframeApiContribution";
|
||||||
import camera from "./Api/iframe/camera";
|
import camera from "./Api/iframe/camera";
|
||||||
|
import {} from "./window";
|
||||||
|
|
||||||
const globalState = createState("global");
|
const globalState = createState("global");
|
||||||
|
|
||||||
@ -182,13 +183,6 @@ const wa = {
|
|||||||
|
|
||||||
export type WorkAdventureApi = typeof wa;
|
export type WorkAdventureApi = typeof wa;
|
||||||
|
|
||||||
declare global {
|
|
||||||
interface Window {
|
|
||||||
WA: WorkAdventureApi;
|
|
||||||
}
|
|
||||||
let WA: WorkAdventureApi;
|
|
||||||
}
|
|
||||||
|
|
||||||
window.WA = wa;
|
window.WA = wa;
|
||||||
|
|
||||||
window.addEventListener(
|
window.addEventListener(
|
||||||
|
@ -16,6 +16,7 @@ import { coWebsiteManager } from "./WebRtc/CoWebsiteManager";
|
|||||||
import { localUserStore } from "./Connexion/LocalUserStore";
|
import { localUserStore } from "./Connexion/LocalUserStore";
|
||||||
import { ErrorScene } from "./Phaser/Reconnecting/ErrorScene";
|
import { ErrorScene } from "./Phaser/Reconnecting/ErrorScene";
|
||||||
import { iframeListener } from "./Api/IframeListener";
|
import { iframeListener } from "./Api/IframeListener";
|
||||||
|
import { desktopApi } from "./Api/desktop/index";
|
||||||
import { SelectCharacterMobileScene } from "./Phaser/Login/SelectCharacterMobileScene";
|
import { SelectCharacterMobileScene } from "./Phaser/Login/SelectCharacterMobileScene";
|
||||||
import { HdpiManager } from "./Phaser/Services/HdpiManager";
|
import { HdpiManager } from "./Phaser/Services/HdpiManager";
|
||||||
import { waScaleManager } from "./Phaser/Services/WaScaleManager";
|
import { waScaleManager } from "./Phaser/Services/WaScaleManager";
|
||||||
@ -154,6 +155,7 @@ coWebsiteManager.onResize.subscribe(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
iframeListener.init();
|
iframeListener.init();
|
||||||
|
desktopApi.init();
|
||||||
|
|
||||||
const app = new App({
|
const app = new App({
|
||||||
target: HtmlUtils.getElementByIdOrFail("game-overlay"),
|
target: HtmlUtils.getElementByIdOrFail("game-overlay"),
|
||||||
|
10
front/src/window.d.ts
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { WorkAdventureApi } from "./iframe_api";
|
||||||
|
import { WorkAdventureDesktopApi } from "@wa-preload-app";
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
WA: WorkAdventureApi;
|
||||||
|
WAD: WorkAdventureDesktopApi;
|
||||||
|
}
|
||||||
|
let WA: WorkAdventureApi;
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env sh
|
||||||
set -x
|
set -x
|
||||||
set -o nounset errexit
|
set -o nounset errexit
|
||||||
index_file=dist/index.html
|
index_file=/usr/share/nginx/html/index.html
|
||||||
tmp_trackcodefile=/tmp/trackcode
|
tmp_trackcodefile=/tmp/trackcode
|
||||||
|
|
||||||
# To inject tracking code, you have two choices:
|
# To inject tracking code, you have two choices:
|
||||||
@ -10,12 +10,12 @@ tmp_trackcodefile=/tmp/trackcode
|
|||||||
# The ANALYTICS_CODE_PATH is the location of a file inside the container
|
# The ANALYTICS_CODE_PATH is the location of a file inside the container
|
||||||
ANALYTICS_CODE_PATH="${ANALYTICS_CODE_PATH:-dist/ga.html.tmpl}"
|
ANALYTICS_CODE_PATH="${ANALYTICS_CODE_PATH:-dist/ga.html.tmpl}"
|
||||||
|
|
||||||
if [[ "${INSERT_ANALYTICS:-NO}" == "NO" ]]; then
|
if [ "${INSERT_ANALYTICS:-NO}" = "NO" ]; then
|
||||||
echo "" > "${tmp_trackcodefile}"
|
echo "" > "${tmp_trackcodefile}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Automatically insert analytics if GA_TRACKING_ID is set
|
# Automatically insert analytics if GA_TRACKING_ID is set
|
||||||
if [[ "${GA_TRACKING_ID:-}" != "" || "${INSERT_ANALYTICS:-NO}" != "NO" ]]; then
|
if [ "${GA_TRACKING_ID:-}" != "" ] || [ "${INSERT_ANALYTICS:-NO}" != "NO" ]; then
|
||||||
echo "Templating code from ${ANALYTICS_CODE_PATH}"
|
echo "Templating code from ${ANALYTICS_CODE_PATH}"
|
||||||
sed "s#<!-- TRACKING NUMBER -->#${GA_TRACKING_ID:-}#g" "${ANALYTICS_CODE_PATH}" > "$tmp_trackcodefile"
|
sed "s#<!-- TRACKING NUMBER -->#${GA_TRACKING_ID:-}#g" "${ANALYTICS_CODE_PATH}" > "$tmp_trackcodefile"
|
||||||
fi
|
fi
|
||||||
|
@ -27,7 +27,10 @@
|
|||||||
"alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
"alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||||
|
|
||||||
"noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
"noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
||||||
"noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */
|
"noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
||||||
|
"paths": {
|
||||||
|
"@wa-preload-app": ["../desktop/electron/src/preload-app/types.ts"],
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"node_modules",
|
"node_modules",
|
||||||
|
@ -482,12 +482,7 @@ ansi-escapes@^4.3.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
type-fest "^0.21.3"
|
type-fest "^0.21.3"
|
||||||
|
|
||||||
ansi-regex@^5.0.0:
|
ansi-regex@^5.0.0, ansi-regex@^5.0.1:
|
||||||
version "5.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
|
|
||||||
integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
|
|
||||||
|
|
||||||
ansi-regex@^5.0.1:
|
|
||||||
version "5.0.1"
|
version "5.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
|
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
|
||||||
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
|
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
|
||||||
|
@ -104,7 +104,7 @@
|
|||||||
"x":0,
|
"x":0,
|
||||||
"y":0
|
"y":0
|
||||||
}],
|
}],
|
||||||
"nextlayerid":9,
|
"nextlayerid":11,
|
||||||
"nextobjectid":13,
|
"nextobjectid":13,
|
||||||
"orientation":"orthogonal",
|
"orientation":"orthogonal",
|
||||||
"properties":[
|
"properties":[
|
||||||
|
@ -13,7 +13,6 @@ export const isRegisterData = new tg.IsInterface()
|
|||||||
organizationMemberToken: tg.isNullable(tg.isString),
|
organizationMemberToken: tg.isNullable(tg.isString),
|
||||||
mapUrlStart: tg.isString,
|
mapUrlStart: tg.isString,
|
||||||
userUuid: tg.isString,
|
userUuid: tg.isString,
|
||||||
// textures: tg.isArray(isCharacterTexture),
|
|
||||||
authToken: tg.isString,
|
authToken: tg.isString,
|
||||||
})
|
})
|
||||||
.withOptionalProperties({
|
.withOptionalProperties({
|
||||||
|
@ -1,17 +1,23 @@
|
|||||||
|
# The building of ProtoBuf "messages" must be done out of Docker because grpc-node does not ship with ARM64 binaries.
|
||||||
|
# See: https://github.com/grpc/grpc-node/issues/1405
|
||||||
|
# When the issue above is closed, we can move back messages building inside Dockerfile
|
||||||
|
|
||||||
# protobuf build
|
# protobuf build
|
||||||
FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as builder
|
#FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as proto-builder
|
||||||
WORKDIR /usr/src
|
#WORKDIR /usr/src
|
||||||
COPY messages .
|
#COPY messages/yarn.lock messages/package.json ./
|
||||||
RUN yarn install && yarn proto
|
#RUN yarn install
|
||||||
|
#COPY messages .
|
||||||
|
#RUN yarn proto
|
||||||
|
|
||||||
# typescript build
|
# typescript build
|
||||||
FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as builder2
|
FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as builder
|
||||||
WORKDIR /usr/src
|
WORKDIR /usr/src
|
||||||
COPY pusher/yarn.lock pusher/package.json ./
|
COPY pusher/yarn.lock pusher/package.json ./
|
||||||
RUN yarn install
|
RUN yarn install
|
||||||
COPY pusher .
|
COPY pusher .
|
||||||
COPY --from=builder /usr/src/generated src/Messages/generated
|
#COPY --from=proto-builder /usr/src/generated src/Messages/generated
|
||||||
COPY --from=builder /usr/src/JsonMessages src/Messages/JsonMessages
|
#COPY --from=proto-builder /usr/src/JsonMessages src/Messages/JsonMessages
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
RUN yarn run tsc
|
RUN yarn run tsc
|
||||||
|
|
||||||
@ -19,9 +25,9 @@ RUN yarn run tsc
|
|||||||
FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d
|
FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d
|
||||||
WORKDIR /usr/src
|
WORKDIR /usr/src
|
||||||
COPY pusher/yarn.lock pusher/package.json ./
|
COPY pusher/yarn.lock pusher/package.json ./
|
||||||
COPY --from=builder2 /usr/src/dist /usr/src/dist
|
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
RUN yarn install --production
|
RUN yarn install --production
|
||||||
|
COPY --from=builder /usr/src/dist /usr/src/dist
|
||||||
|
|
||||||
USER node
|
USER node
|
||||||
CMD ["yarn", "run", "runprod"]
|
CMD ["yarn", "run", "runprod"]
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"tsc": "tsc",
|
"tsc": "tsc && cp -rf ./data ./dist/",
|
||||||
"dev": "ts-node-dev --respawn ./server.ts",
|
"dev": "ts-node-dev --respawn ./server.ts",
|
||||||
"prod": "tsc && node --max-old-space-size=4096 ./dist/server.js",
|
"prod": "tsc && cp -rf ./data ./dist/ && node --max-old-space-size=4096 ./dist/server.js",
|
||||||
"runprod": "node --max-old-space-size=4096 ./dist/server.js",
|
"runprod": "node --max-old-space-size=4096 ./dist/server.js",
|
||||||
"profile": "tsc && node --prof ./dist/server.js",
|
"profile": "tsc && node --prof ./dist/server.js",
|
||||||
"test": "ts-node node_modules/jasmine/bin/jasmine --config=jasmine.json",
|
"test": "ts-node node_modules/jasmine/bin/jasmine --config=jasmine.json",
|
||||||
|
@ -61,6 +61,7 @@ export class AdminController extends BaseHttpController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
res.send("ok");
|
res.send("ok");
|
||||||
|
return;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +140,13 @@ export class AuthenticateController extends BaseHttpController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const resCheckTokenAuth = await openIDClient.checkTokenAuth(authTokenData.accessToken);
|
const resCheckTokenAuth = await openIDClient.checkTokenAuth(authTokenData.accessToken);
|
||||||
return res.json({ ...resCheckTokenAuth, ...resUserData, authToken: token });
|
return res.json({
|
||||||
|
...resCheckTokenAuth,
|
||||||
|
...resUserData,
|
||||||
|
authToken: token,
|
||||||
|
username: authTokenData?.username,
|
||||||
|
locale: authTokenData?.locale,
|
||||||
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.info("User was not connected", err);
|
console.info("User was not connected", err);
|
||||||
}
|
}
|
||||||
@ -161,13 +167,18 @@ export class AuthenticateController extends BaseHttpController {
|
|||||||
if (!email) {
|
if (!email) {
|
||||||
throw new Error("No email in the response");
|
throw new Error("No email in the response");
|
||||||
}
|
}
|
||||||
const authToken = jwtTokenManager.createAuthToken(email, userInfo?.access_token);
|
const authToken = jwtTokenManager.createAuthToken(
|
||||||
|
email,
|
||||||
|
userInfo?.access_token,
|
||||||
|
userInfo?.username,
|
||||||
|
userInfo?.locale
|
||||||
|
);
|
||||||
|
|
||||||
//Get user data from Admin Back Office
|
//Get user data from Admin Back Office
|
||||||
//This is very important to create User Local in LocalStorage in WorkAdventure
|
//This is very important to create User Local in LocalStorage in WorkAdventure
|
||||||
const data = await this.getUserByUserIdentifier(email, playUri as string, IPAddress);
|
const data = await this.getUserByUserIdentifier(email, playUri as string, IPAddress);
|
||||||
|
|
||||||
return res.json({ ...data, authToken });
|
return res.json({ ...data, authToken, username: userInfo?.username, locale: userInfo?.locale });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("openIDCallback => ERROR", e);
|
console.error("openIDCallback => ERROR", e);
|
||||||
return this.castErrorToResponse(e, res);
|
return this.castErrorToResponse(e, res);
|
||||||
@ -204,7 +215,7 @@ export class AuthenticateController extends BaseHttpController {
|
|||||||
console.error("openIDCallback => logout-callback", error);
|
console.error("openIDCallback => logout-callback", error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res.status(200).send("");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,6 +371,7 @@ export class AuthenticateController extends BaseHttpController {
|
|||||||
//get login profile
|
//get login profile
|
||||||
res.status(302);
|
res.status(302);
|
||||||
res.setHeader("Location", adminApi.getProfileUrl(authTokenData.accessToken));
|
res.setHeader("Location", adminApi.getProfileUrl(authTokenData.accessToken));
|
||||||
|
res.send("");
|
||||||
return;
|
return;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.castErrorToResponse(error, res);
|
this.castErrorToResponse(error, res);
|
||||||
|
@ -37,9 +37,11 @@ export class BaseHttpController {
|
|||||||
" " +
|
" " +
|
||||||
(e.response.data && e.response.data.message ? e.response.data.message : e.response.statusText)
|
(e.response.data && e.response.data.message ? e.response.data.message : e.response.statusText)
|
||||||
);
|
);
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
res.status(500);
|
res.status(500);
|
||||||
res.send("An error occurred");
|
res.send("An error occurred");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|