├── .actrc
├── .editorconfig
├── .eslintignore
├── .eslintrc.json
├── .gitattributes
├── .github
├── ISSUE_TEMPLATE
│ ├── bug.yml
│ ├── build_failures.md
│ ├── config.yml
│ └── feature_request.yml
└── workflows
│ ├── build.yml
│ ├── codeql-analysis.yml
│ ├── njsscan.yml
│ ├── potential-duplicates.yml
│ ├── prerelease.yml
│ └── release.yml
├── .gitignore
├── .husky
├── core.sh
└── pre-commit
├── .npmrc
├── LICENSE
├── docs
├── Build.md
├── Contributing.md
├── FAQ.md
├── Features.md
├── Files.md
├── Flags.md
├── Privacy.md
├── Readme.md
├── Repos.md
├── Support.md
└── pl
│ └── Readme.md
├── package-lock.json
├── package.json
├── schemas
├── localization
│ └── settings.json
└── schemastore
│ ├── LICENSE
│ ├── NOTICE
│ └── package.json
├── sources
├── assets
│ ├── icons
│ │ ├── app.icns
│ │ ├── app.ico
│ │ ├── app.png
│ │ ├── symbols
│ │ │ ├── checkmark.svg
│ │ │ ├── close.svg
│ │ │ ├── menu.svg
│ │ │ └── speaker.svg
│ │ ├── tray-ping.png
│ │ ├── tray-unread.png
│ │ └── tray.png
│ └── web
│ │ ├── css
│ │ ├── about.css
│ │ ├── capturer.css
│ │ ├── discord.css
│ │ ├── fonts.css
│ │ ├── global.css
│ │ ├── load.css
│ │ ├── markdown.css
│ │ └── settings.css
│ │ ├── html
│ │ ├── 404.html
│ │ ├── about.html
│ │ ├── capturer.html
│ │ ├── docs.html
│ │ ├── load.html
│ │ └── settings.html
│ │ └── json
│ │ └── motd.json
├── code
│ ├── build
│ │ └── forge.mts
│ ├── common
│ │ ├── global.ts
│ │ ├── main.ts
│ │ └── modules
│ │ │ ├── agent.ts
│ │ │ ├── client.ts
│ │ │ ├── electron.ts
│ │ │ ├── l10n.ts
│ │ │ └── package.ts
│ ├── main
│ │ ├── modules
│ │ │ ├── bug.ts
│ │ │ ├── config.ts
│ │ │ ├── csp.ts
│ │ │ ├── error.ts
│ │ │ ├── extensions.ts
│ │ │ ├── menu.ts
│ │ │ ├── optimize.ts
│ │ │ ├── parent.ts
│ │ │ ├── socket.mts
│ │ │ └── update.ts
│ │ └── windows
│ │ │ ├── about.ts
│ │ │ ├── docs.ts
│ │ │ ├── main.ts
│ │ │ └── settings.ts
│ ├── renderer
│ │ ├── modules
│ │ │ └── api.ts
│ │ └── preload
│ │ │ ├── about.ts
│ │ │ ├── capturer.ts
│ │ │ ├── docs.ts
│ │ │ ├── main.ts
│ │ │ └── settings.ts
│ └── utility
│ │ └── ws.ts
└── translations
│ ├── ar
│ ├── client.json
│ ├── settings.json
│ └── web.json
│ ├── ca
│ ├── client.json
│ ├── settings.json
│ └── web.json
│ ├── de
│ ├── client.json
│ ├── settings.json
│ └── web.json
│ ├── el
│ ├── client.json
│ ├── settings.json
│ └── web.json
│ ├── en
│ ├── client.json
│ ├── settings.json
│ └── web.json
│ ├── es-MX
│ ├── client.json
│ ├── settings.json
│ └── web.json
│ ├── es
│ ├── client.json
│ ├── settings.json
│ └── web.json
│ ├── fr
│ ├── client.json
│ ├── settings.json
│ └── web.json
│ ├── it
│ ├── client.json
│ ├── settings.json
│ └── web.json
│ ├── ja
│ ├── client.json
│ ├── settings.json
│ └── web.json
│ ├── nb
│ ├── client.json
│ ├── settings.json
│ └── web.json
│ ├── nl
│ ├── client.json
│ ├── settings.json
│ └── web.json
│ ├── pl
│ ├── client.json
│ ├── settings.json
│ └── web.json
│ ├── pt
│ ├── client.json
│ ├── settings.json
│ └── web.json
│ ├── ru
│ ├── client.json
│ ├── settings.json
│ └── web.json
│ ├── ta
│ ├── client.json
│ ├── settings.json
│ └── web.json
│ ├── tr
│ ├── client.json
│ ├── settings.json
│ └── web.json
│ └── uk
│ ├── client.json
│ ├── settings.json
│ └── web.json
└── tsconfig.json
/.actrc:
--------------------------------------------------------------------------------
1 | # Workaround for an issue with act's invalid `.gitignore` parsing.
2 | --use-gitignore=false
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*.{ts,json}]
4 | charset = utf-8
5 | trim_trailing_whitespace = true
6 | end_of_line = lf
7 | indent_size = 2
8 | indent_style = space
9 | insert_final_newline = false
10 |
11 | [package{,-lock}.json]
12 | insert_final_newline = true
13 |
14 | [tsconfig.json]
15 | indent_size = 4
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | app/
2 | node_modules/
3 | cache/
4 | .*
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 | *.png binary
3 | *.ico binary
4 | *.icns binary
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/build_failures.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Build failure report.
3 | about: Report issues when building / packaging the application.
4 | title: ''
5 | labels: 'type:build'
6 | assignees: SpacingBat3
7 |
8 | ---
9 |
10 |
19 |
20 | ### Acknowledgements ###
21 |
22 | - [ ] There's no other issue describing the same problem, regardless of its current state (i.e. including both closed and open issues).\*
23 | - [ ] There's no fix for my issue released to `master` branch.\*
24 | - [ ] This issue has known workaround (write it below).
25 |
26 | * Required
27 |
28 | ### Environment ###
29 |
33 | - Platform: [e.g. `🐧️ linux`]
34 | - Architecture: [e.g `arm64`/`aarch64`]
35 | - Electron version: [e.g. `v12.0.7`]
36 | - Electron Forge version: [e.g. `v6.3.0`]
37 | - Application version: [e.g. `v4.4.0`]
38 | - TypeScript compiler version: [e.g. `5.0.0`]
39 | - Node.js package manager: [e.g. `npm`]
40 | - Node.js package manger version: [e.g. `9.8.1`]
41 |
42 | ### Describe the problem ###
43 | A clear and concise description of where the build and package process fails.
44 |
45 | ### To Reproduce ###
46 | Steps to reproduce the behaviour:
47 | 1. Go to '...'
48 | 2. Click on '....'
49 | 3. Scroll down to '....'
50 | 4. See error.
51 |
52 | ### Expected behaviour ###
53 | A clear and concise description of what you expected to happen.
54 |
55 | ### Screenshots ###
56 | If applicable, add screenshots to help explain your problem.
57 |
58 | ### Additional context ###
59 | Add any other context about the problem here.
60 |
61 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 | contact_links:
3 | - name: FlatHub's bug tracker
4 | url: https://github.com/flathub/io.github.spacingbat3.webcord/issues
5 | about: Report issues regarding to Flatpaks (otherwise make sure it is reproducible ouside of the flatpaks).
6 | - name: Discord server
7 | url: https://discord.gg/aw7WbDMua5
8 | about: Talk, ask questions and give feedback via Discord.
9 | - name: Discussions
10 | url: https://github.com/SpacingBat3/WebCord/discussions
11 | about: Talk, ask questions and give feedback via GitHub Discussions.
12 | - name: Email
13 | url: mailto:git@spacingbat3.anonaddy.com
14 | about: Contact me via e-mail (I might respond with another e-mail address).
15 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.yml:
--------------------------------------------------------------------------------
1 | name: Feature request
2 | description: Suggest an idea for this project.
3 | assignees: ['SpacingBat3']
4 | labels: ['type:feat']
5 | body:
6 | - type: textarea
7 | id:
8 | attributes:
9 | label: Description
10 | description: Is your feature request related to a problem? Please describe.
11 | placeholder: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 | - type: textarea
13 | id:
14 | attributes:
15 | label: Suggestions
16 | description: Describe the solution you'd like.
17 | placeholder: A clear and concise description of what you want to happen.
18 | - type: textarea
19 | id:
20 | attributes:
21 | label: Alternatives
22 | description: Describe alternatives you've considered.
23 | placeholder: A clear and concise description of any alternative solutions or features you've considered.
24 | - type: textarea
25 | id: context
26 | attributes:
27 | label: Additional Context
28 | description: Add any other context or screenshots about the feature request here.
29 | placeholder: |
30 | Additional information, screenshot, videos... Ex. This feature request
31 | is only related to Unix (Linux, BSD) builds.
32 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build distributables
2 | on:
3 | push:
4 | branches-ignore:
5 | - 'v*'
6 | paths-ignore:
7 | - 'docs/**'
8 | - '.github/ISSUE_TEMPLATE/**'
9 | pull_request:
10 | paths-ignore:
11 | - 'docs/**'
12 | - '.github/ISSUE_TEMPLATE/**'
13 | branches-ignore:
14 | - 'v*'
15 |
16 | env:
17 | WEBCORD_BUILD: DEVEL
18 |
19 | permissions: {}
20 |
21 | jobs:
22 | test:
23 | strategy:
24 | matrix:
25 | deps: ['latest', 'locked']
26 | name: "Test build"
27 | runs-on: ubuntu-latest
28 | steps:
29 | - uses: actions/checkout@v4
30 | - uses: actions/setup-node@v4
31 | with:
32 | node-version: latest
33 | cache: npm
34 |
35 | - name: Install dependencies (NPM)
36 | run: npm ci
37 |
38 | - name: Update dependencies
39 | if: ${{ matrix.deps == 'latest' }}
40 | run: npm update
41 |
42 | - name: TSC cache
43 | uses: actions/cache@v4
44 | with:
45 | key: tsc-${{ matrix.deps }}
46 | path: |
47 | app
48 | cache/tsc.json
49 |
50 | - name: ESLint cache
51 | uses: actions/cache@v4
52 | with:
53 | key: eslint-${{ matrix.deps }}
54 | path: |
55 | cache/eslint.json
56 |
57 | - name: Run tests with ${{ matrix.deps }} dependencies
58 | run: npm test
59 | make:
60 | strategy:
61 | fail-fast: false
62 | matrix:
63 | name: ['Linux', 'Windows', 'macOS-x64', 'macOS-arm64']
64 | build: [latest, locked]
65 | include:
66 | - runner: ubuntu-latest
67 | name: Linux
68 | arch: x64,arm64,armv7l
69 | - runner: windows-latest
70 | name: Windows
71 | arch: x64,arm64,ia32
72 | - runner: macos-latest
73 | name: macOS-x64
74 | arch: x64 #,arm64,universal
75 | - runner: macos-14
76 | name: macOS-arm64
77 | arch: arm64
78 |
79 | name: '${{ matrix.name }} (${{ matrix.build }})'
80 | runs-on: ${{ matrix.runner }}
81 | needs: ['test']
82 | steps:
83 | - uses: actions/checkout@v4
84 | - uses: actions/setup-node@v4
85 | with:
86 | node-version: 'latest'
87 | cache: npm
88 |
89 | - name: Install dependencies (NPM)
90 | run: npm ci
91 |
92 | - name: Update dependencies
93 | if: ${{ matrix.build == 'latest' }}
94 | run: npm update
95 |
96 | - name: TSC cache
97 | uses: actions/cache@v4
98 | with:
99 | key: tsc-${{ matrix.build }}
100 | path: |
101 | app
102 | cache/tsc.json
103 |
104 | - name: Generate distributables (${{ matrix.arch }})
105 | uses: nick-fields/retry@v2
106 | with:
107 | retry_on: error
108 | max_attempts: 3
109 | timeout_minutes: 10
110 | command: npm run make -- -a ${{ matrix.arch }}
111 |
112 | - name: Upload distributables as artifact
113 | uses: actions/upload-artifact@v4
114 | with:
115 | name: ${{ matrix.name }}_${{ matrix.build }}
116 | path: out/devel/make/*
117 |
118 | - name: Upload lockfile as artifact
119 | if: ${{ matrix.build == 'latest' }}
120 | uses: actions/upload-artifact@v4
121 | with:
122 | name: ${{ matrix.name }}-lockfile_updated
123 | path: package-lock.json
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL"
13 |
14 | on:
15 | push:
16 | branches: [ "master" ]
17 | pull_request:
18 | # The branches below must be a subset of the branches above
19 | branches: [ "master" ]
20 | schedule:
21 | - cron: '28 12 * * 3'
22 |
23 | jobs:
24 | analyze:
25 | name: Analyze
26 | runs-on: ubuntu-latest
27 | permissions:
28 | actions: read
29 | contents: read
30 | security-events: write
31 |
32 | strategy:
33 | fail-fast: false
34 | matrix:
35 | language: [ 'javascript' ]
36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
37 | # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
38 |
39 | steps:
40 | - name: Checkout repository
41 | uses: actions/checkout@v3
42 |
43 | # Initializes the CodeQL tools for scanning.
44 | - name: Initialize CodeQL
45 | uses: github/codeql-action/init@v2
46 | with:
47 | languages: ${{ matrix.language }}
48 | # If you wish to specify custom queries, you can do so here or in a config file.
49 | # By default, queries listed here will override any specified in a config file.
50 | # Prefix the list here with "+" to use these queries and those in the config file.
51 |
52 | # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
53 | # queries: security-extended,security-and-quality
54 |
55 |
56 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
57 | # If this step fails, then you should remove it and run the build manually (see below)
58 | - name: Autobuild
59 | uses: github/codeql-action/autobuild@v2
60 |
61 | # ℹ️ Command-line programs to run using the OS shell.
62 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
63 |
64 | # If the Autobuild fails above, remove it and uncomment the following three lines.
65 | # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
66 |
67 | # - run: |
68 | # echo "Run, Build Application using script"
69 | # ./location_of_script_within_repo/buildscript.sh
70 |
71 | - name: Perform CodeQL Analysis
72 | uses: github/codeql-action/analyze@v2
73 |
--------------------------------------------------------------------------------
/.github/workflows/njsscan.yml:
--------------------------------------------------------------------------------
1 | # This workflow integrates njsscan with GitHub's Code Scanning feature
2 |
3 | name: "NJSScan"
4 |
5 | on:
6 | push:
7 | branches: [ "master" ]
8 | pull_request:
9 | branches: [ "master" ]
10 | schedule:
11 | - cron: '28 12 * * 3'
12 |
13 | permissions:
14 | contents: read
15 |
16 | jobs:
17 | njsscan:
18 | permissions:
19 | contents: read # for actions/checkout to fetch code
20 | security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
21 | actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status
22 | runs-on: ubuntu-latest
23 | name: njsscan code scanning
24 | steps:
25 | - name: Checkout the code
26 | uses: actions/checkout@v3
27 | - name: nodejsscan scan
28 | id: njsscan
29 | uses: ajinabraham/njsscan-action@7237412fdd36af517e2745077cedbf9d6900d711
30 | with:
31 | args: '. --sarif --output results.sarif || true'
32 | - name: Upload njsscan report
33 | uses: github/codeql-action/upload-sarif@v2
34 | with:
35 | sarif_file: results.sarif
36 |
--------------------------------------------------------------------------------
/.github/workflows/potential-duplicates.yml:
--------------------------------------------------------------------------------
1 | name: Check issues for potential duplicates
2 | on:
3 | issues:
4 | types: [opened, edited]
5 | jobs:
6 | run:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - uses: wow-actions/potential-duplicates@v1
10 | with:
11 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
12 | exclude: 'WebCord Discord Fosscord broken bug'
13 | state: all
14 | threshold: 0.6
15 | reactions: 'confused'
16 | comment: |
17 | Potential duplicates: {{#issues}}
18 | - [#{{ number }}] {{ title }} ({{ accuracy }}%)
19 | {{/issues}}
20 |
--------------------------------------------------------------------------------
/.github/workflows/prerelease.yml:
--------------------------------------------------------------------------------
1 | name: Publish pre-release
2 | on:
3 | push:
4 | tags: ['*beta*']
5 |
6 | env:
7 | WEBCORD_BUILD: DEVEL
8 |
9 | permissions:
10 | contents: write
11 |
12 | jobs:
13 | publish:
14 | strategy:
15 | matrix:
16 | include:
17 | - name: Linux
18 | runner: ubuntu-latest
19 | arch: x64,arm64,armv7l
20 | - name: Windows
21 | runner: windows-latest
22 | arch: x64,arm64,ia32
23 | - name: macOS-x64
24 | runner: macos-latest
25 | arch: x64 #,arm64,universal
26 | - name: macOS-arm64
27 | runner: macos-14
28 | arch: arm64
29 |
30 | name: ${{ matrix.name }} (${{ matrix.arch }})
31 | runs-on: ${{ matrix.runner }}
32 | steps:
33 | - uses: actions/checkout@v4
34 | - uses: actions/setup-node@v4
35 | with:
36 | node-version: 'latest'
37 | cache: npm
38 |
39 | - name: Install dependencies (NPM)
40 | run: npm ci
41 |
42 | - name: TSC cache
43 | uses: actions/cache@v4
44 | with:
45 | key: tsc-release
46 | path: |
47 | app
48 | cache/tsc.json
49 |
50 | - name: Publish distributables (${{ matrix.arch}})
51 | uses: nick-fields/retry@v2
52 | env:
53 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
54 | with:
55 | retry_on: error
56 | max_attempts: ${{ matrix.name == 'Windows' && 6 || 3 }}
57 | timeout_minutes: ${{ matrix.name == 'Windows' && 15 || 10 }}
58 | command: npm run publish -- -a ${{ matrix.arch }}
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Publish release
2 | on:
3 | push:
4 | tags-ignore: ['*beta*']
5 |
6 | env:
7 | WEBCORD_BUILD: RELEASE
8 |
9 | permissions:
10 | contents: write
11 |
12 | jobs:
13 | publish:
14 | strategy:
15 | matrix:
16 | include:
17 | - name: Linux
18 | runner: ubuntu-latest
19 | arch: x64,arm64,armv7l
20 | - name: Windows
21 | runner: windows-latest
22 | arch: x64,arm64,ia32
23 | - name: macOS-x64
24 | runner: macos-latest
25 | arch: x64 #,arm64,universal
26 | - name: macOS-arm64
27 | runner: macos-14
28 | arch: arm64
29 |
30 | name: ${{ matrix.name }} (${{ matrix.arch }})
31 | runs-on: ${{ matrix.runner }}
32 | steps:
33 | - uses: actions/checkout@v4
34 | - uses: actions/setup-node@v4
35 | with:
36 | node-version: 'latest'
37 | cache: npm
38 |
39 | - name: Install dependencies (NPM)
40 | run: npm ci
41 |
42 | - name: TSC cache
43 | uses: actions/cache@v4
44 | with:
45 | key: tsc-prerelease
46 | path: |
47 | app
48 | cache/tsc.json
49 |
50 | - name: Publish distributables (${{ matrix.arch}})
51 | uses: nick-fields/retry@v2
52 | env:
53 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
54 | with:
55 | retry_on: error
56 | max_attempts: ${{ matrix.name == 'Windows' && 6 || 3 }}
57 | timeout_minutes: ${{ matrix.name == 'Windows' && 15 || 10 }}
58 | command: npm run publish -- -a ${{ matrix.arch }}
59 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore build / packaging artifacts
2 | out/
3 | app/
4 | cache/
5 | # Ignore Node package managers artifacts
6 | node_modules/
7 | # Ignore foreign lockfiles
8 | *lock*
9 | !package-lock.json
10 | # Ignore hidden dirs with some exceptions
11 | # (these are likely used by text editors)
12 | .*/
13 | # GitHub – workflows, templates, configs etc.
14 | !.github/
15 | # Husky – Git hooks implementation
16 | !.husky/
17 | .husky/_/
--------------------------------------------------------------------------------
/.husky/core.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # shellcheck shell=bash
3 | #
4 | # Core utilities for hooks
5 | #
6 |
7 | # `npkg` – finds first available Node package manager and wraps it for common
8 | # syntax so it can be used for scripts.
9 | #
10 | # **Usage:**
11 | # ```sh
12 | # npkg {add|run|test|install} [ARGS]
13 | # ```
14 | # shellcheck disable=SC2317
15 | npkg() {
16 | local PKG SUPPORT;
17 | # A path to Node.js package manager.
18 | PKG="$(command -v npm || command -v yarn || command -v pnpm || echo false)";
19 | # A list of supported package manager commands
20 | SUPPORT=(install test run add);
21 | _install() {
22 | case "${PKG##*/}" in
23 | "npm"|"yarn"|"pnpm") printf "install";;
24 | *) return 127;;
25 | esac
26 | }
27 | _test() {
28 | case "${PKG##*/}" in
29 | "npm"|"yarn"|"pnpm") printf "test";;
30 | *) return 127;;
31 | esac
32 | }
33 | _run() {
34 | case "${PKG##*/}" in
35 | "npm"|"yarn"|"pnpm") printf "run";;
36 | *) return 127;;
37 | esac
38 | }
39 | _add() {
40 | case "${PKG##*/}" in
41 | "npm"|"pnpm") printf "install";;
42 | "yarn") printf "add";;
43 | *) return 127;;
44 | esac
45 | }
46 | # Syntax checks.
47 | {
48 | # Unknown package manager (or lack of it).
49 | if [[ "$PKG" == "false" ]]; then
50 | echo "npkg: Couldn't find any supported Node manager!" >&2
51 | echo "npkg: Search list: 1.npm 2.yarn 3.pnpm" >&2
52 | return 200
53 | fi
54 | # Lack of first argument
55 | if [[ -z "$1" ]]; then
56 | echo "npkg: No command specified!" >&2
57 | echo "npkg: Supported commands: ${SUPPORT[*]}!" >&2
58 | return 202
59 | fi
60 | local VALID=0
61 | for cmd in "${SUPPORT[@]}"; do
62 | [[ "$1" == "$cmd" ]] && VALID=1
63 | done
64 | if [[ $VALID == 0 ]]; then
65 | echo "npkg: Unknown command: '${1}'!" >&2
66 | echo "npkg: Supported commands: ${SUPPORT[*]}!" >&2
67 | return 127
68 | fi
69 | }
70 | printf '\n%s\n\n' "npkg: Selected package manager: '${PKG##*/}'."
71 | "$PKG" "$("_$1")" "${@:2}"
72 | }
73 |
74 | # `c_json` – `JSON.parse()` wrapper for BASH. Part of `core.sh`.
75 | #
76 | # **Usage:**
77 | # ```sh
78 | # c_json .[property] PATH
79 | # ```
80 | c_json() {
81 | local query file;
82 | if [[ "$1" == "." ]]; then
83 | query="";
84 | else
85 | query="$1";
86 | fi
87 | file="$(tr -d '\n' <<< "${2//'"'/'\\"'}")";
88 | node -e "console.log(JSON.parse(\"$file\")$query);";
89 | return $?;
90 | }
91 |
92 | # `c_svcom` – A SemVer comparassion for BASH.
93 | #
94 | # **Usage:**
95 | # ```
96 | # c_svcom ()
97 | # ```
98 | c_svcom() {
99 | local sedrule subvr_1 subvr_2 vtype;
100 | case "$1" in
101 | maj{,or}) vtype=1 ;;
102 | min{,ior}) vtype=2 ;;
103 | patch) vtype=3 ;;
104 | *) vtype="$1" ;;
105 | esac
106 | if [[ "$vtype" -lt 1 || "$vtype" -gt 3 ]]; then return 1; fi;
107 | sedrule="s/.*\([\^<]\)\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\1 \\$((vtype+1))/";
108 | mapfile -t subvr_1 < <(sed "$sedrule" <<< "$2");
109 | mapfile -t subvr_2 < <(sed "$sedrule" <<< "$3");
110 | if [[ "${subvr_1[0]}" != "${subvr_2[0]}" ]]; then return 2; fi;
111 | if [[ "${subvr_1[1]}" -gt "${subvr_2[1]}" ]]; then
112 | echo 1;
113 | elif [[ "${subvr_1[1]}" -eq "${subvr_2[1]}" ]]; then
114 | echo 0;
115 | elif [[ "${subvr_1[1]}" -lt "${subvr_2[1]}" ]]; then
116 | echo -1;
117 | fi
118 | return 3;
119 | }
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env -S sh -e
2 | # shellcheck shell=bash
3 |
4 | if [ -z "$husky_shell_switch" ]; then
5 | readonly husky_shell_switch=1;
6 | export husky_shell_switch;
7 | # Use BASH instead of SH with Husky.
8 | # (Not all scripts are POSIX-compilant).
9 | exec bash -e "$0" "$@";
10 | fi
11 |
12 | . "$(dirname -- "$0")/core.sh";
13 |
14 | PKGROOT="$(dirname -- "$0")/..";
15 |
16 | # Check metadata files.
17 |
18 | mapfile -t FILES < <(git diff --staged --name-only);
19 | lock=false;
20 | meta=false;
21 | for file in "${FILES[@]}"; do
22 | if [[ "$file" == "package-lock.json" ]]; then
23 | lock=true;
24 | elif [[ "$file" == "package.json" ]]; then
25 | meta=true;
26 | fi
27 | if [[ $lock == "true" && $meta == "true" ]]; then break; fi
28 | done
29 | if [[ "$meta" == "false" && "$lock" == "true" ]]; then
30 | echo >&2;
31 | echo "pre-commit: unnecesary-lockfile" >&2;
32 | printf ' %s\n' \
33 | "It seems that you've tried to commit a lock file without any changes"\
34 | "done in 'package.json'! This operation will be blocked as lockfile"\
35 | "should not be bumped unless a development tree has changed in some way"\
36 | "or commit is made that bumps package version and the new tag is going"\
37 | "to be released" >&2
38 | echo >&2;
39 | exit 1;
40 | elif [[ "$meta" == "true" && "$lock" == "false" ]]; then
41 | old="$(git show HEAD:/package.json)";
42 | new="$(cat "$PKGROOT/package.json")";
43 | versions=(
44 | "$(c_svcomp 1 "$(c_json .version "$new")" "$(c_json .version "$old")")"
45 | "$(c_svcomp 1 "$(c_json .dependencies.electron"$new")" "$(c_json .dependencies.electron "$ld")")"
46 | )
47 | if [[ "${versions[0]}" -eq 0 && "${versions[1]}" -eq 1 ]]; then
48 | echo >&2;
49 | echo "pre-commit: breaking-deps!" >&2;
50 | printf ' %s\n' \
51 | "It seems that you've tried to commit a 'package.json' file in which"\
52 | "there was made a major release bump to Electron. This change is considered"
53 | "as 'breaking' because it can announce new bugs into the application due"\
54 | "to the API changes, Chromium/Node.js bump and potentially untested"\
55 | "features which has been recently announced. For this reason, WebCord"\
56 | "should be bumped to the next major version as well." >&2
57 | echo >&2;
58 | exit 2;
59 | fi
60 | fi
61 |
62 | # Run package tests (compiler+linter).
63 |
64 | npkg test;
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | lockfile-version=3
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020-2023 Dawid Papiewski "SpacingBat3"
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/docs/Build.md:
--------------------------------------------------------------------------------
1 | # Working with the sources
2 |
3 | When working with the WebCord, there're many tools you may have to use to be
4 | able to compile it from TypeScript to JavaScript, package it to the
5 | distributable format, run linter and so on. This section will describe the
6 | commands you may need to know to proceed with its development or packaging it
7 | yourself from its source code.
8 |
9 | > [!NOTE]
10 | > To simplify the documentation, only npm
command syntax is
11 | > shown below. If you prefer using another package manager, you're free to
12 | > do so as in my philosophy you should not be limited with the set of
13 | > tools used by maintainers and have the right to choose your own.
14 |
15 | > [!WARNING]
16 | > WebCord comes with package-lock.json
as a lock file format
17 | > and your preferred package manager might not be functional with it. You
18 | > still can install the latest dependencies, yet the created lockfile will
19 | > not be used to reproduce the tested environment when a dependency
20 | > breakage will occur.
21 |
22 | ## Install app dependencies.
23 |
24 | This is the first command you need to execute – without that, you won't be able
25 | to proceed with the app testing and run most of the commands listed in
26 | `package.json`.
27 | ```sh
28 | npm ci
29 | ```
30 |
31 | This command uses `package-lock.json` which contains resolved package tree for
32 | faster package installations. While `package-lock.json` contains the dependency
33 | tree confirmed to work in the past or in case of the releases it can also be
34 | used to reproduce the builds, you might want to opt-in for the latest
35 | *non-breaking* (according to `semver` specification) dependencies that might
36 | contain bug fixes and security patches. This normally won't cause any breakages
37 | and you could still go back to the previous state with `git` if anything goes
38 | wrong.
39 |
40 | To update dependencies to the latest version available:
41 |
42 | ```
43 | npm update
44 | ```
45 |
46 | Be aware that `npm ci` will also install the development dependencies. **This is**
47 | **probably what you want**, as those dependencies includes all of the
48 | recommended packages required for compiling, linting and packaging WebCord. If
49 | you however want to install the production dependencies only (i.e. you want to
50 | use your own set of the tools or have installed them globally with `npm i -g`),
51 | you can use the following command instead:
52 | ```
53 | npm i --only=prod
54 | ```
55 |
56 | ## Compile code and run app directly (without packaging).
57 |
58 | After you have installed all required `dependencies` and `devDependencies`, you
59 | can use the following command to incrementally compile WebCord's source code
60 | from TypeScript to JavaScript:
61 | ```
62 | npm run build
63 | ```
64 |
65 | To both compile code and start application even before it is packaged:
66 | ```
67 | npm start
68 | ```
69 |
70 | ## Run linter and validate the code.
71 |
72 | While developing, you may want to check if your code quality is enough to be
73 | accepted as part of the WebCord project. To do that, you may want to both
74 | compile it (to ensure there're no compiler errors) and run linter (to check for
75 | the other issues). To do this, you can use the command below:
76 | ```
77 | npm test
78 | ```
79 |
80 | You can also run linter only if you don't want to compile the code:
81 | ```
82 | npm run lint
83 | ```
84 |
85 | ## Packaging / creating distributables.
86 |
87 | If you want to share with someone the binaries of your packaged application, or
88 | just install and/or use it without the source code and development packages,
89 | you can generate all distributable files that are valid for your platform using
90 | following command:
91 | ```
92 | npm run make
93 | ```
94 |
95 | You can also create a directory containing a packaged app. This directory isn't
96 | adapted for a specific distributable format, but it contains the Electron binary
97 | with the compiled application, which needs to be set up manually if you want to
98 | install it within your OS. To package an application without packing it as
99 | distributable, execute the following command:
100 | ```
101 | npm run package
102 | ```
103 |
104 | This will package the app for your current platform.
105 |
106 | ## Build environment variables.
107 |
108 | While making app distributables with the `npm run make` you can use some
109 | environment variables that will take effect on the application before it is
110 | packaged. See [`Flags.md`](./Flags.md#1-in-electron-forge) for the further
111 | information.
--------------------------------------------------------------------------------
/docs/Contributing.md:
--------------------------------------------------------------------------------
1 | # How to contribute in the project?
2 |
3 | This file describes the ways of contributing to the project.
4 |
5 | ## How do I report a bug or request a new feature?
6 |
7 | You can do this via the application's menu bar or the tray menu. Application will
8 | then generate a link to the new GitHub issue with the pre-filled details about
9 | your operating system (you still need to describe the issue through, it doesn't
10 | automatically send a bug report for you). You can also report issues via the
11 | project's GitHub repository.
12 |
13 | When creating a GitHub issue, please take a look:
14 |
15 | - if there're any similar issues (including the closed ones); if so, try to
16 | describe your issue under that one or ask to reopen it to bring me attention;
17 |
18 | - if your issue can be reproduced within the web version – fixing Discord
19 | bugs there isn't for now the priority of this project and could cause a
20 | possible breakages on the site updates;
21 |
22 | ## How could I work within app development and create a pull request?
23 |
24 | When working with the WebCord's source code, I recommend reading the
25 | documentation about [each of the files](./Files.md) and what is their purpose in
26 | WebCord to know where you should put your code within the existing files. I'm
27 | also encouraging to read the following parts of the documentation:
28 |
29 | - [`Build.md`], to know more about current WebCord's development script syntax,
30 | including how to compile, test and package source files.
31 |
32 | - [`Flags.md`], to know a little more about the current build flags
33 | implementation.
34 |
35 | ## How to translate WebCord?
36 |
37 | Currently, WebCord has moved its translation to its [Weblate instance][weblate].
38 | It includes the current state of the translation project, instructions and
39 | limitations. You are free to translate it *the old way* (by doing a PR), yet
40 | Weblate changes might be pulled earlier in order to avoid conflicts on Weblate
41 | side.
42 |
43 | ## Other ways of the contribution:
44 |
45 | You can also help to maintain this project by:
46 | - taking part in / answering GitHub discussions,
47 | - helping me to solve issues,
48 | - updating / working on the documentation,
49 | - reviewing the WebCord's source code or pull requests and suggesting the
50 | changes.
51 |
52 | [`Build.md`]: Build.md
53 | [`Flags.md`]: Flags.md
54 | [weblate]: https://hosted.weblate.org/projects/spacingbat3-webcord
--------------------------------------------------------------------------------
/docs/Flags.md:
--------------------------------------------------------------------------------
1 | # Command line (runtime) flags
2 |
3 | WebCord is capable of parsing some Chromium flags and following
4 | application-specific flags:
5 |
6 | - **`--start-minimized` or `-m`** – start WebCord minimized in tray;
7 | useful when running WebCord at system start;
8 |
9 | - **`--version` or `-V`** – display application version and exit even before
10 | *app is ready*.
11 |
12 | - **`--help`, `-?` or `-h`** – display help information about the application.
13 |
14 | - **`--export-l10n={dir}`** – export currently loaded translations as a set of
15 | JSON files to the **`{dir}`** directory.
16 |
17 | - **`--verbose` or `-v`** – show debug messages.
18 |
19 | - **`--gpu-info=basic|complete`** – displays a raw GPU information from Chromium
20 | in form of a JavaScript object.
21 |
22 | # Build flags:
23 |
24 | ## 1. In Electron Forge
25 |
26 | While packaging the application with the Electron Forge, WebCord supports
27 | following build environment variables to set build specific flags:
28 |
29 | - `WEBCORD_BUILD={release,stable,devel}` – if set to `release` or `stable`,
30 | WebCord will be build as a stable release, with some experimental features
31 | disabled that are not meant for production build. Default build type is
32 | `devel`.
33 |
34 | - `WEBCORD_ASAR={true,false}` – if set to `false`, WebCord won't be packaged to
35 | the `asar` archive. Default is `true`.
36 |
37 | - `WEBCORD_UPDATE_NOTIFICATIONS={true,false}` – if set to `false`, notifications
38 | won't show on the new updates; this feature is meant for the package
39 | maintainers so they can disable the notifications for their users and let the
40 | package manager to handle the update notifications.
41 |
42 | - `WEBCORD_WIN32_APPID=[string]` *(Windows only)* – replaces the `ApplicationUserModelID`, used
43 | as an unique application identifier. Default is `SpacingBat3.WebCord`. You
44 | should replace it if you want to differ your build from the official ones,
45 | e.g. if you release your own WebCord package for Windows with your own
46 | patches and want to allow for coexisting it with the official WebCord
47 | executables.
48 |
49 | - `WEBCORD_FLATPAK_ID=[string]` *(Linux only)* – Used in Flatpak manifest file
50 | as an unique app identifier. For community builds it should be set to
51 | something else. Defaults to `io.github.spacingbat3.webcord`
52 |
53 | ## 2. Other tools
54 |
55 | If you're packaging the application on your own, you can create directly a
56 | `buildInfo.json` file, which is used internally by WebCord do determine the
57 | state of the build environment flags (except `asar` packaging, this is what you
58 | need to implement or configure with your own Electron packaging software).
59 | The `buildInfo.json` file should be placed in the application's root directory
60 | (i.e. next to `package.json`) and contain following properties:
61 |
62 | - `"type": "devel"/"release"` – similarly to `WEBCORD_BUILD`, this controls
63 | whenever this build is meant for production use or for development purposes.
64 | If not set, WebCord's build type will be set as `devel`.
65 |
66 | - `"commit": [hash]` – this property will save the information about the build
67 | commit; it is ignored for the `release` build type.
68 |
69 | - `AppUserModelId: [string]` *(Windows only)* – defines an
70 | `ApplicationUserModelId` of the WebCord build, this should always be present
71 | in Windows distributables.
72 |
73 | - `"features": [Object]` – this is the object controlling some features;
74 | currently it can contain these optional properties:
75 |
76 | - `"updateNotifications": true/false` – whenever to show notifications on
77 | the new releases; this does not disable the update checker to print the
78 | its current status in the console (i.e. if the version is out-of-date).
--------------------------------------------------------------------------------
/docs/Privacy.md:
--------------------------------------------------------------------------------
1 | ## Privacy Policy
2 |
3 | This software **does not** share any data to its owner/maintainers – user
4 | configuration, session details and cookies are saved locally. However because
5 | this software connects to [Discord website](https://discord.com/app) as well as
6 | Fosscord instances (depending on user selection), the application may share some
7 | data or even track you depending on the WebCord's configuration. By default,
8 | WebCord tries to protect the user privacy and does not grant sensitive
9 | permissions as well as mitigate the tracing by blocking some of the unnecessary
10 | request made by the client itself.
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./schemas/schemastore/package.json",
3 | "name": "webcord",
4 | "productName": "WebCord",
5 | "version": "4.11.0",
6 | "description": "A Discord made with the Electron API.",
7 | "main": "app/code/common/main.js",
8 | "scripts": {
9 | "prepare": "husky",
10 | "test": "tsc && ESLINT_USE_FLAT_CONFIG=false eslint --cache --cache-location cache/eslint.json --ext .ts .",
11 | "lint": "ESLINT_USE_FLAT_CONFIG=false eslint --cache --cache-location cache/eslint.json --ext .ts .",
12 | "build": "tsc",
13 | "compile": "tsc",
14 | "tsc": "tsc",
15 | "watch": "tsc --watch",
16 | "start": "tsc && electron .",
17 | "package": "tsc && electron-forge package",
18 | "make": "tsc && electron-forge make",
19 | "publish": "tsc && electron-forge publish",
20 | "prepack": "tsc && electron-forge package && echo 'This script will now fail to cancel creating a Node package...' && exit 1"
21 | },
22 | "author": {
23 | "name": "SpacingBat3",
24 | "email": "git@spacingbat3.anonaddy.com",
25 | "url": "https://github.com/SpacingBat3"
26 | },
27 | "license": "MIT",
28 | "repository": {
29 | "type": "git",
30 | "url": "git+https://github.com/SpacingBat3/WebCord"
31 | },
32 | "bugs": {
33 | "url": "https://github.com/SpacingBat3/WebCord/issues"
34 | },
35 | "homepage": "https://github.com/SpacingBat3/WebCord#readme",
36 | "devDependencies": {
37 | "@electron-forge/cli": "^7.1.0",
38 | "@electron-forge/maker-deb": "^7.1.0",
39 | "@electron-forge/maker-dmg": "^7.1.0",
40 | "@electron-forge/maker-flatpak": "^7.1.0",
41 | "@electron-forge/maker-rpm": "^7.1.0",
42 | "@electron-forge/maker-snap": "^7.1.0",
43 | "@electron-forge/maker-squirrel": "^7.1.0",
44 | "@electron-forge/maker-wix": "^7.1.0",
45 | "@electron-forge/maker-zip": "^7.1.0",
46 | "@electron-forge/plugin-fuses": "^7.1.0",
47 | "@electron-forge/publisher-github": "^7.1.0",
48 | "@electron/fuses": "^1.5.0",
49 | "@reforged/maker-appimage": "^5.0.0",
50 | "@stylistic/eslint-plugin": "^4.2.0",
51 | "@tsconfig/strictest": "^2.0.0",
52 | "@types/node": "^20.16.1",
53 | "@types/semver": "^7.3.9",
54 | "@types/source-map-support": "^0.5.4",
55 | "@types/ws": "^8.5.1",
56 | "@typescript-eslint/eslint-plugin": "^8.2.0",
57 | "electron": "^36.2.0",
58 | "eslint": "latest",
59 | "eslint-import-resolver-typescript": "latest",
60 | "eslint-plugin-import": "latest",
61 | "husky": "^9.0.0",
62 | "typescript": "^5.0.4"
63 | },
64 | "dependencies": {
65 | "@spacingbat3/disconnection": "^1.0.3",
66 | "@spacingbat3/kolor": "^4.0.0",
67 | "deepmerge-ts": "^7.0.3",
68 | "dompurify": "^3.0.1",
69 | "marked": "^15.0.4",
70 | "marked-alert": "^2.1.2",
71 | "marked-gfm-heading-id": "^4.0.0",
72 | "semver": "^7.3.5",
73 | "source-map-support": "^0.5.21",
74 | "tslib": "^2.3.1",
75 | "twemoji-colr-font": "^15.0.3"
76 | },
77 | "config": {
78 | "forge": "./app/code/build/forge.mjs"
79 | },
80 | "engines": {
81 | "node": "^16.10.0 || ^18.10.0 || >=19.0.0",
82 | "npm": ">=8.0.0"
83 | },
84 | "private": true
85 | }
86 |
--------------------------------------------------------------------------------
/schemas/localization/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/draft-04/schema#",
3 | "title": "JSON schema for configuration window (settings.json) localization files.",
4 | "definitions": {
5 | "subsection": {
6 | "description": "A subsection defining a configuration for specific functionality of the application.",
7 | "type": "object",
8 | "required": ["name","description"],
9 | "properties": {
10 | "name": {
11 | "type": "string",
12 | "description": "A short name for this subsection. Rendered in uppercase letters. Should be short, but can be little longer section name. It shouldn't end with a full stop symbol since it shouldn't be a sentence."
13 | },
14 | "description": {
15 | "type": "string",
16 | "description": "A detailed description of this subsection. Preferably, you should include the non-breaking spaces in order to describe how breaks should occur in this text. You can also use some HTML tags for text formatting, others will be sanitized for security reasons. It should end with a full stop symbol as it should be a sententce."
17 | },
18 | "labels": {
19 | "type": "object",
20 | "description": "A labels of input elements associated with this subsection",
21 | "additionalProperties": {
22 | "type": "string",
23 | "description": "A label for input element with the same id or name as this entry key. You can use there HTML tags for text formatting, others will be sanitized for security reasons. It should end with a full stop symbol when it is a sentence."
24 | }
25 | },
26 | "info": {
27 | "type": "object",
28 | "description": "Description for each of the elements in \"labels\". This can be used to further explain it, to keep \"labels\" short and uncluttered.",
29 | "additionalProperties": {
30 | "type": "string",
31 | "description": "A title for input element with the same id or name as this entry key. It should end with a full stop symbol when it is a sentence."
32 | }
33 | }
34 | },
35 | "additionalProperties": false
36 | },
37 | "section": {
38 | "description": "One of top-level sections in rendered configuration window. Groups features by their type, e.g. features associated with the user privacy are inside the \"Privacy\" section.",
39 | "type": "object",
40 | "required": ["name"],
41 | "properties": {
42 | "name": {
43 | "type": "string",
44 | "description": "A name of this section. While there are no limitations to this property value length, it is recommended to keep it as short and concise as possible. It should not end with a full stop symbol as this property value should not be a sentence."
45 | }
46 | },
47 | "additionalProperties": {
48 | "$ref": "#/definitions/subsection"
49 | }
50 | }
51 | },
52 | "properties": {
53 | "$schema": {
54 | "type": "string",
55 | "description": "A path to settings.json JSON schema. DO NOT CHANGE THIS WHEN CREATING NEW LOCALIZATION FILES."
56 | }
57 | },
58 | "additionalProperties": {
59 | "$ref": "#/definitions/section"
60 | }
61 | }
--------------------------------------------------------------------------------
/schemas/schemastore/NOTICE:
--------------------------------------------------------------------------------
1 | The JSON schemas in this folder are modified version of schemas distributed at
2 | and should not be considered as a part of this
3 | software. They're distributed specifically for this software, to bring better
4 | suggestions to supported text editors for JSON files included as part of this
5 | software.
6 |
7 | I DO NOT CLAIM ANY KIND OF OWNERSHIP OF THIS FILES AND BY THAT MEANING THEY'RE
8 | DISTRIBUTED UNDER SAME CONDITIONS AS IT IS IN CASE OF SCHEMA STORE FILES.
9 |
10 | This is the copyright notice took from NOTICE file from schemastore
11 | GitHub repository:
12 |
13 | JSON Schema Store
14 | Copyright 2015-Current Mads Kristensen and Contributors
15 |
16 | The Apache license is also distributed with these schema stores as it is in
17 | original GitHub project.
--------------------------------------------------------------------------------
/sources/assets/icons/app.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SpacingBat3/WebCord/085fe5f5030d6f24d9c553fcc90039a5cf916257/sources/assets/icons/app.icns
--------------------------------------------------------------------------------
/sources/assets/icons/app.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SpacingBat3/WebCord/085fe5f5030d6f24d9c553fcc90039a5cf916257/sources/assets/icons/app.ico
--------------------------------------------------------------------------------
/sources/assets/icons/app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SpacingBat3/WebCord/085fe5f5030d6f24d9c553fcc90039a5cf916257/sources/assets/icons/app.png
--------------------------------------------------------------------------------
/sources/assets/icons/symbols/checkmark.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/sources/assets/icons/symbols/close.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/sources/assets/icons/symbols/menu.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/sources/assets/icons/symbols/speaker.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/sources/assets/icons/tray-ping.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SpacingBat3/WebCord/085fe5f5030d6f24d9c553fcc90039a5cf916257/sources/assets/icons/tray-ping.png
--------------------------------------------------------------------------------
/sources/assets/icons/tray-unread.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SpacingBat3/WebCord/085fe5f5030d6f24d9c553fcc90039a5cf916257/sources/assets/icons/tray-unread.png
--------------------------------------------------------------------------------
/sources/assets/icons/tray.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SpacingBat3/WebCord/085fe5f5030d6f24d9c553fcc90039a5cf916257/sources/assets/icons/tray.png
--------------------------------------------------------------------------------
/sources/assets/web/css/capturer.css:
--------------------------------------------------------------------------------
1 | @import "./global.css";
2 |
3 | html, body {
4 | background-color: transparent;
5 | }
6 |
7 | #capturer-selection {
8 | position: fixed;
9 | top: 0;
10 | left: 0;
11 | width: 100%;
12 | height: 100vh;
13 | background: #000a;
14 | color: var(--color-font-normal);
15 | display: flex;
16 | align-items: center;
17 | justify-content: center;
18 | }
19 |
20 | #capturer-scroller {
21 | width: 100%;
22 | max-height: 100vh;
23 | overflow-y: auto;
24 | }
25 |
26 | #capturer-list {
27 | max-width: calc(100% - 100px);
28 | margin: 50px;
29 | padding: 0;
30 | display: flex;
31 | flex-wrap: wrap;
32 | list-style: none;
33 | overflow: hidden;
34 | justify-content: center;
35 | }
36 |
37 | .capturer-item {
38 | display: flex;
39 | margin: 4px;
40 | }
41 |
42 | .capturer-button {
43 | cursor: pointer;
44 | display: flex;
45 | flex-direction: column;
46 | align-items: stretch;
47 | width: 145px;
48 | margin: 0;
49 | border: 0;
50 | border-radius: 3px;
51 | padding: 4px;
52 | color: #FFFFFF;
53 | background: var(--color-input-bg);
54 | text-align: left;
55 | transition: background-color .15s, box-shadow .15s;
56 | }
57 |
58 | .capturer-button:hover,
59 | .capturer-button:focus {
60 | background: var(--color-accent);
61 | }
62 | .capturer-thumbnail {
63 | width: 100%;
64 | height: 81px;
65 | object-fit: cover;
66 | }
67 | .capturer-label-container {
68 | margin: 6px 0 6px;
69 | display: flex;
70 | flex-shrink: 0;
71 | flex-grow: 0;
72 | }
73 |
74 | .capturer-label-icon {
75 | width: 16px;
76 | padding-right: 4px;
77 | }
78 |
79 | .capturer-label {
80 | color: #dcddde;
81 | white-space: nowrap;
82 | text-overflow: ellipsis;
83 | overflow: hidden;
84 | }
85 |
86 | #capturer-buttons {
87 | position: fixed;
88 | display: flex;
89 | flex-direction: column;
90 | right: 15px;
91 | top: 50%;
92 | transform: translateY(-50%);
93 | }
94 |
95 | #capturer-buttons > * {
96 | display: flex;
97 | cursor: pointer;
98 | justify-content: center;
99 | align-items: center;
100 | background-color: var(--color-input-bg);
101 | color: #dcddde;
102 | width: 32px;
103 | height: 32px;
104 | transition: background-color .15s;
105 | border: transparent;
106 | border-radius: 3px;
107 | box-shadow: none;
108 | margin: 2px 0;
109 | }
110 |
111 | #capturer-buttons > * > img {
112 | margin: 0;
113 | padding: 0;
114 | width: 14px;
115 | }
116 |
117 | #capturer-buttons > *:hover {
118 | background-color: #678;
119 | }
120 |
121 | #capturer-buttons button#capturer-close:active {
122 | background-color: #c24242;
123 | }
124 |
125 | input[type="checkbox"]#capturer-sound {
126 | appearance: none;
127 | flex-shrink: 0;
128 | background-image: url("../../icons/symbols/speaker.svg");
129 | background-repeat: no-repeat;
130 | background-position: center;
131 | background-size: 16px;
132 | }
133 |
134 | #capturer-sound:checked {
135 | background-color: var(--color-accent);
136 | }
137 |
138 | #capturer-buttons > *:disabled {
139 | background-color: var(--color-bg-secondary);
140 | cursor: not-allowed;
141 | }
--------------------------------------------------------------------------------
/sources/assets/web/css/discord.css:
--------------------------------------------------------------------------------
1 | /* Animate side bar on resize. */
2 | div[class^=sidebar_]
3 | div[class^=sidebarList_] {
4 | transition: width .1s cubic-bezier(0.4, 0, 0.2, 1);
5 | }
6 |
7 | /* Hide Discord elements. */
8 | div[class^=scroller_] > div[class^=listItem_]:nth-last-child(2) > *,
9 | div[class^=scroller_] > div[class^=listItem_]:nth-last-child(3) > *,
10 | div[class*=" scroller_"] > div[class^="listItem_"]:nth-last-child(2) {
11 | display: none !important;
12 | }
13 |
14 | /* Assign 'rainbow' color to my nickname! */
15 | img[src*="423864076095979522"] ~ :is(h1,h2,h3,h4,h5,h6) > span > span {
16 | animation: rainbow linear 20s infinite;
17 | }
18 |
19 | :root {
20 | --neon-shadow: 0 0 3px;
21 | }
22 |
23 | .theme-dark {
24 | --rb: 75%
25 | }
26 |
27 | .theme-light {
28 | --rb: 35%
29 | }
30 |
31 | @keyframes rainbow {
32 | 0% {
33 | color: hsl(0, 100%, var(--rb));
34 | text-shadow: var(--neon-shadow) hsl(0, 100%, var(--rb));
35 | }
36 | 15% {
37 | color: hsl(39, 100%, calc(var(--rb) - 5%));
38 | text-shadow: var(--neon-shadow) hsl(39, 100%, calc(var(--rb) - 5%));
39 | }
40 | 30% {
41 | color: hsl(60, 100%, calc(var(--rb) - 10%));
42 | text-shadow: var(--neon-shadow) hsl(60, 100%, calc(var(--rb) - 10%));
43 | }
44 | 45% {
45 | color: hsl(120, 100%, calc(var(--rb) - 5%));
46 | text-shadow: var(--neon-shadow) hsl(120, 100%, calc(var(--rb) - 5%));
47 | }
48 | 60% {
49 | color: hsl(240, 100%, calc(var(--rb) + 6%));
50 | text-shadow: var(--neon-shadow) hsl(240, 100%, calc(var(--rb) + 6%));
51 | }
52 | 75% {
53 | color: hsl(275, 100%, calc(var(--rb) + 4%));
54 | text-shadow: var(--neon-shadow) hsl(275, 100%, calc(var(--rb) + 4%));
55 | }
56 | 90% {
57 | color: hsl(300, 100%, calc(var(--rb) + 2%));
58 | text-shadow: var(--neon-shadow) hsl(300, 100%, calc(var(--rb) + 2%));
59 | }
60 | 100% {
61 | color: hsl(360, 100%, var(--rb));
62 | text-shadow: var(--neon-shadow) hsl(360, 100%, var(--rb));
63 | }
64 | }
65 |
66 | div[class^=bar_] {
67 | height: 0px;
68 | }
69 |
70 | /* Hide "help" button. */
71 | div[class^=toolbar_] > a {
72 | display: none;
73 | }
74 |
75 | /* Fix popup position going negative. Also sets fixed toolbar popup position. */
76 | div[id^=popout_]:is([style*="; right: -"],[style*="; top: 44px;"]) {
77 | right: 16px !important;
78 | }
79 |
80 | /* Limit elements width to not take space above the screen width. */
81 | div[class^=layerContainer_] :not([class*=Tooltip]) {
82 | max-width: 100vw;
83 | }
84 |
85 | /* Mobile interface tweaks */
86 | @media screen and (max-width: 480px) {
87 | div[class^=channelTextArea_] > div[class^=scrollableContainer_] >
88 | div[class^=inner_] > div[class^=buttons_] > :not(:nth-last-child(2)) {
89 | display: none;
90 | }
91 | /* Hide search input if the screen is too small to display toolbar right.*/
92 | section[class^=title_] > div[class^=toolbar_] > div[class^=search_] {
93 | display: none;
94 | }
95 | /* Fix popup position being to far from the right/left. */
96 | div[id^=popout_][style] {
97 | right: 0px !important;
98 | left: unset !important;
99 | }
100 | /* Fix size of some popups take slightly higher width than they should be. */
101 | div[role=dialog] div[class^=header_] {
102 | box-sizing: border-box;
103 | }
104 | }
--------------------------------------------------------------------------------
/sources/assets/web/css/fonts.css:
--------------------------------------------------------------------------------
1 | /** Twemoji **/
2 | @import url('../../../../node_modules/twemoji-colr-font/twemoji.css');
3 |
4 | :root {
5 | --font-primary: sans-serif, Twemoji;
6 | --font-display: sans-serif, Twemoji;
7 | --font-code: monospace, Twemoji;
8 | --font-headline: var(--font-display);
9 | }
--------------------------------------------------------------------------------
/sources/assets/web/css/global.css:
--------------------------------------------------------------------------------
1 | @import "./fonts.css";
2 |
3 | /* A CSS that imitates the Discord's style, with some minior tweaks. */
4 |
5 | :root {
6 | --color-accent: #4185d3;
7 | --color-accent-alt: #287baf;
8 | --color-accent-light: 140, 202, 255;
9 | --color-bg-primary: #36393F;
10 | --color-bg-secondary: #2F3136;
11 | --color-bg-border: #1B1C1F;
12 | --color-font-settings: #8e9297;
13 | --color-font-code: #b9bbbe;
14 | --color-font-normal: #dcddde;
15 | --color-font-header: #fff;
16 | --color-link: #00A3E3;
17 | --color-input-bg: #484C52;
18 | --scrollbar-width: 7px;
19 | --scrollbar-thumb: #202225;
20 | --color-alert-info: 83, 163, 248;
21 | --color-alert-warn: 248, 197, 29;
22 | }
23 |
24 | html {
25 | margin: 0 10px;
26 | user-select: none;
27 | font-family: var(--font-primary);
28 | background-color: var(--color-bg-primary);
29 | color: var(--color-font-normal);
30 | line-height: 1.5;
31 | }
32 |
33 | h1, h2, h3, h4, h5, h6 {
34 | color: var(--color-font-header);
35 | font-family: var(--font-display);
36 | margin-top: 1em;
37 | margin-bottom: 0.5em;
38 | }
39 |
40 | ::-webkit-scrollbar {
41 | width: var(--scrollbar-width);
42 | height: var(--scrollbar-width);
43 | background-color: transparent;
44 | border-radius: 25px;
45 | }
46 |
47 | ::-webkit-scrollbar-thumb {
48 | display: none;
49 | background-color: var(--scrollbar-thumb);
50 | border-radius: 25px;
51 | box-sizing: border-box;
52 | border: solid transparent 2px;
53 | }
54 |
55 | :hover > ::-webkit-scrollbar-thumb {
56 | display: unset;
57 | }
58 |
59 | ::-webkit-scrollbar-thumb:active {
60 | background-color: var(--color-bg-border);
61 | }
62 |
63 | a {
64 | color: var(--color-link);
65 | text-decoration: unset;
66 | }
67 |
68 | a:hover {
69 | text-decoration: underline;
70 | }
71 |
72 | table {
73 | border-collapse: collapse;
74 | border-spacing: 0;
75 | margin-bottom: 1em;
76 | }
77 |
78 | td, th {
79 | padding: 8px;
80 | }
81 |
82 | tr:nth-child(odd) {
83 | background-color: var(--color-bg-secondary);
84 | }
85 |
86 | th {
87 | color: var(--color-font-header);
88 | background-color: var(--color-accent);
89 | }
90 |
91 | html :not(pre) > code {
92 | font-size: 0.8em;
93 | padding: 4px;
94 | margin-top: 0px;
95 | background-color: var(--color-bg-secondary);
96 | border-radius: 5px;
97 | }
98 |
99 | code {
100 | font-family: var(--font-code);
101 | font-size: 1em;
102 | }
103 |
104 | kbd {
105 | position: relative;
106 | font-size: 1em;
107 | background-color: var(--color-input-bg);
108 | color: var(--color-font-header);
109 | font-weight: bold;
110 | text-transform: uppercase;
111 | border-radius: 3px;
112 | box-shadow: var(--color-bg-border) 0px 4px;
113 | border: 1px solid transparent;
114 | padding: 2px 6px;
115 | margin-right: 2px;
116 | margin-left: 2px;
117 | top: -1px;
118 | }
119 |
120 | kbd:active {
121 | border-color: var(--color-bg-border);
122 | box-shadow: inset var(--color-bg-primary) 0px -2px;
123 | color: var(--color-font-normal);
124 | top: 0px;
125 | padding-bottom: 4px;
126 | }
127 |
128 | pre {
129 | display: block;
130 | border: 1px solid var(--color-bg-border);
131 | padding: 16px 12px;
132 | background-color: var(--color-bg-secondary);
133 | color: var(--color-font-code);
134 | font-family: var(--font-code);
135 | overflow: auto;
136 | border-radius: 15px;
137 | font-size: 10pt;
138 | }
139 |
140 | li {
141 | margin: 0.5em 0em;
142 | }
143 |
144 | a, img {
145 | user-select: none;
146 | -webkit-user-drag: none;
147 | -webkit-user-select: none;
148 | }
149 |
150 | blockquote {
151 | margin-inline-start: 30px;
152 | padding-left: 10px;
153 | border-left: 4px solid var(--color-input-bg);
154 | color: var(--color-font-settings);
155 | }
156 |
157 | hr {
158 | color: var(--color-input-bg);
159 | background-color: var(--color-input-bg);
160 | border: solid 2px var(--color-input-bg);
161 | }
--------------------------------------------------------------------------------
/sources/assets/web/css/load.css:
--------------------------------------------------------------------------------
1 | @import "./global.css";
2 |
3 | :root {
4 | --content-width: 300px;
5 | }
6 |
7 | html, body {
8 | margin: 0;
9 | background-color: #36393F;
10 | height: 100%;
11 | }
12 |
13 | body, div.aura {
14 | text-align: center;
15 | display: flex;
16 | margin: 0px;
17 | align-items: center;
18 | justify-content: center;
19 | flex-direction: column;
20 | }
21 |
22 | h1 {
23 | margin-top: 0.5em;
24 | }
25 |
26 | .aura-content {
27 | width: var(--content-width);
28 | margin-left: calc(50vw - (var(--content-width)/2));
29 | margin-right: calc(50vw - (var(--content-width)/2));
30 | overflow: hidden;
31 | white-space: normal;
32 | }
33 |
34 | .aura {
35 | height: 100%;
36 | width: 100%;
37 | background-color: var(--color-accent);
38 | animation-name: aura;
39 | animation-duration: 1s;
40 | animation-timing-function: ease-in-out;
41 | animation-fill-mode: forwards;
42 | white-space: nowrap;
43 | overflow: hidden;
44 | text-overflow: clip;
45 | }
46 |
47 | @keyframes aura {
48 | 0% {width: 0%}
49 | 10% {width: 0%;background-color: var(--color-accent)}
50 | 100% {width: 100%;background-color: transparent}
51 | }
--------------------------------------------------------------------------------
/sources/assets/web/css/markdown.css:
--------------------------------------------------------------------------------
1 | @import "./global.css";
2 |
3 | :root {
4 | --header-height: 36px;
5 | }
6 |
7 | p, li, div {
8 | font-size: 11pt;
9 | }
10 |
11 | img {
12 | max-height: 256px;
13 | }
14 |
15 | code, pre {
16 | font-size: 9pt;
17 | }
18 |
19 | sup {
20 | font-size: 8pt;
21 | }
22 |
23 | h1, h2, h3, h4, h5, h6 {
24 | color: var(--color-font-header);
25 | font-family: var(--font-display);
26 | margin-top: 1em;
27 | margin-bottom: 0.5em;
28 | scroll-margin-top: 0.5em;
29 | }
30 |
31 | h1, h2 {
32 | border-bottom: 2px solid var(--color-input-bg);
33 | padding-bottom: 5px;
34 | }
35 |
36 | h1 {
37 | margin-top: 0;
38 | }
39 |
40 | h1#webcord {
41 | font-size: xx-large;
42 | }
43 |
44 | #markdown-body > h1:first-child,
45 | #markdown-body > h2:first-child,
46 | #markdown-body > h3:first-child,
47 | #markdown-body > h4:first-child,
48 | #markdown-body > h5:first-child,
49 | #markdown-body > h6:first-child {
50 | margin-top: 0.5em;
51 | }
52 |
53 | html {
54 | width: 100vw;
55 | height: 100vh;
56 | }
57 |
58 | body {
59 | width: 100%;
60 | height: 100%;
61 | }
62 |
63 | html, body {
64 | margin: 0px;
65 | }
66 |
67 | article {
68 | width: 100vw;
69 | margin: 0px;
70 | overflow: auto;
71 | position: absolute;
72 | top: var(--header-height);
73 | bottom: 0;
74 | }
75 |
76 | #markdown-body {
77 | margin: 0px 16px;
78 | padding-top: 1em;
79 | }
80 |
81 | #markdown-header {
82 | padding-right: 24px;
83 | background-color: var(--color-bg-primary);
84 | border-bottom: 2px solid var(--color-bg-secondary);
85 | display: flex;
86 | justify-content: center;
87 | align-items: center;
88 | position: sticky;
89 | top: 0;
90 | height: var(--header-height);
91 | }
92 |
93 | #menu-hamburger {
94 | margin: 0px 5px;
95 | padding: 4px;
96 | width: 22px;
97 | height: 22px;
98 | border-radius: 8px;
99 | transition: background-color 0.5s ease-in-out;
100 | }
101 |
102 | #markdown-header p {
103 | font-family: var(--font-primary);
104 | color: var(--color-font-header);
105 | font-size: 16pt;
106 | font-weight: bold;
107 | }
108 |
109 | #menu-hamburger:hover {
110 | cursor: pointer;
111 | background-color: #fff3;
112 | transition: background-color 0.5s ease-in-out;
113 | }
114 |
115 | .markdown-alert {
116 | border-style: solid;
117 | border-width: 4px;
118 | border-radius: 16px;
119 | padding: 4px 16px;
120 | margin-bottom: 1em;
121 | }
122 |
123 | .markdown-alert-note {
124 | background-color: rgba(var(--color-alert-info), 15%);
125 | border-color: rgb(var(--color-alert-info));
126 | }
127 |
128 | .markdown-alert-note .markdown-alert-title {
129 | color: rgb(var(--color-alert-info));
130 | fill: rgb(var(--color-alert-info));
131 | }
132 |
133 | .markdown-alert-warning {
134 | background-color: rgba(var(--color-alert-warn), 20%);
135 | border-color: rgb(var(--color-alert-warn));
136 |
137 | }
138 |
139 | .markdown-alert-warning .markdown-alert-title {
140 | color: rgb(var(--color-alert-warn));
141 | fill: rgb(var(--color-alert-warn));
142 | }
143 |
144 |
145 | .markdown-alert-title {
146 | font-weight: bold;
147 | display: flex;
148 | align-items: center;
149 | }
150 |
151 | .markdown-alert .octicon {
152 | margin-right: 4px;
153 | }
154 |
155 | table.alert-info > tbody > tr:only-child {
156 | background-color: rgba(var(--color-alert-info), 20%);
157 | border-color: rgb(var(--color-alert-info));
158 | }
159 |
160 | table.alert-warn > tbody > tr:only-child {
161 | background-color: rgba(var(--color-alert-warn), 20%);
162 | border-color: rgb(var(--color-alert-warn));
163 | }
--------------------------------------------------------------------------------
/sources/assets/web/css/settings.css:
--------------------------------------------------------------------------------
1 | @import "./global.css";
2 |
3 | h1 {
4 | font-size: 1.6em;
5 | }
6 |
7 | h2 {
8 | margin-left: 15px;
9 | font-size: 0.8em;
10 | text-transform: uppercase;
11 |
12 | }
13 |
14 | p.description {
15 | font-size: 0.8em;
16 | margin: 0 15px 1em 15px;
17 | color: var(--color-font-settings);
18 | }
19 |
20 | form {
21 | display: flex;
22 | overflow-x: hidden;
23 | flex-direction: column;
24 | margin: 0 40px 2em 40px;
25 | padding: 10px 15px;
26 | background-color: var(--color-bg-secondary);
27 | font-size: 0.8em;
28 | border-radius: 5px;
29 | }
30 |
31 | fieldset {
32 | display: flex;
33 | margin: 0.5em 0px;
34 | padding: 0;
35 | border: none;
36 | }
37 |
38 | label {
39 | margin-top: 0.15em;
40 | font-size: 1em;
41 | }
42 |
43 | label.disabled {
44 | color: var(--color-font-settings);
45 | }
46 |
47 | input, label {
48 | cursor: pointer;
49 | }
50 |
51 | input:disabled, label.disabled {
52 | cursor: default;
53 | }
54 |
55 | input[type="checkbox"], input[type="radio"] {
56 | flex-shrink: 0;
57 | margin: 0 1em;
58 | height: 1.5em;
59 | width: 1.5em;
60 | border-radius: 5px;
61 | appearance: none;
62 | background-color: var(--color-input-bg);
63 | transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
64 | border: solid #0000 4px;
65 | }
66 |
67 | input[type="radio"] {
68 | border-radius: 100%;
69 | background-color: var(--color-bg-secondary);
70 | border: solid var(--color-bg-secondary) 4px;
71 | outline: none;
72 | box-shadow: 0px 0px 0px 2px var(--color-font-normal);
73 |
74 | }
75 |
76 | input[type="checkbox"] {
77 | border-color: var(--color-input-bg);
78 | }
79 |
80 | input[type="radio"]:disabled {
81 | outline-color: var(--color-font-settings);
82 | }
83 |
84 | input[type="checkbox"]:checked {
85 | background-color: var(--color-accent);
86 | background-image: url(../../icons/symbols/checkmark.svg);
87 | background-repeat: no-repeat;
88 | background-position: center;
89 | background-size: contain;
90 | border-color: var(--color-accent);
91 | }
92 |
93 | input[type="radio"]:checked {
94 | background-color: rgb(var(--color-accent-light));
95 | outline-color: var(--color-font-header)
96 |
97 | }
98 |
99 | code {
100 | background-color: var(--color-bg-primary) !important;
101 | font-size: 0.9em !important;
102 | }
--------------------------------------------------------------------------------
/sources/assets/web/html/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
21 |
22 |
23 |
35 |
36 |
--------------------------------------------------------------------------------
/sources/assets/web/html/about.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
23 |
24 |
25 |
26 |
27 |
28 |
![]()
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
Electron / Chromium / Node
37 |
38 |
39 |
40 |
44 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
100 |
101 |
--------------------------------------------------------------------------------
/sources/assets/web/html/capturer.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Screen Share
8 |
9 |
10 |
11 |
22 |
23 |
--------------------------------------------------------------------------------
/sources/assets/web/html/docs.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |