mirror of
https://github.com/stoatchat/for-legacy-web.git
synced 2026-03-07 09:25:27 +00:00
Compare commits
12 Commits
ui/bot-pro
...
ui/setting
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bba9689e30 | ||
|
|
cc76e78db8 | ||
|
|
d2d7083542 | ||
|
|
73d99e4518 | ||
|
|
f14ef2b78f | ||
|
|
4719150368 | ||
|
|
3d73834bef | ||
|
|
1aff8ef516 | ||
|
|
b80a6a9c3e | ||
|
|
1780d06c97 | ||
|
|
c29efc155b | ||
|
|
71c0a782c1 |
6
.github/workflows/mirroring.yml
vendored
6
.github/workflows/mirroring.yml
vendored
@@ -1,6 +1,10 @@
|
|||||||
name: Mirroring
|
name: Mirroring
|
||||||
|
|
||||||
on: [push, delete]
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "master"
|
||||||
|
- "production"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
to_gitlab:
|
to_gitlab:
|
||||||
|
|||||||
39
.github/workflows/preview_cleanup.yml
vendored
39
.github/workflows/preview_cleanup.yml
vendored
@@ -1,39 +0,0 @@
|
|||||||
name: Clean Preview
|
|
||||||
|
|
||||||
#! Safety:
|
|
||||||
#! this workflow should not execute any untrusted input at all
|
|
||||||
#! see the docs on `pull_request_target` for more
|
|
||||||
on:
|
|
||||||
pull_request_target:
|
|
||||||
types: [unlabeled]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
clean:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: github.event.label.name == 'use-preview'
|
|
||||||
env:
|
|
||||||
BASE: refs/pull/${{ github.event.pull_request.number }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
ref: build-previews
|
|
||||||
persist-credentials: false
|
|
||||||
|
|
||||||
- name: clean previews
|
|
||||||
run: rm -rf "$BASE"
|
|
||||||
|
|
||||||
- name: publish cleaned previews
|
|
||||||
uses: JamesIves/github-pages-deploy-action@4.1.5
|
|
||||||
with:
|
|
||||||
folder: .
|
|
||||||
branch: build-previews
|
|
||||||
commit-message: "Cleaning up build result for #${{ github.event.pull_request.number }}"
|
|
||||||
|
|
||||||
- name: send comment
|
|
||||||
uses: marocchino/sticky-pull-request-comment@v2
|
|
||||||
with:
|
|
||||||
header: Preview environment
|
|
||||||
message: |
|
|
||||||
## Preview environment
|
|
||||||
There is no longer a preview enviroment for this pull request due to the `use-preview` label being removed
|
|
||||||
52
.github/workflows/preview_pull_request.yml
vendored
52
.github/workflows/preview_pull_request.yml
vendored
@@ -1,52 +0,0 @@
|
|||||||
name: Preview Pull Request
|
|
||||||
|
|
||||||
#! Safety:
|
|
||||||
#! this workflow should not execute any untrusted input at all
|
|
||||||
#! see the docs on `pull_request_target` for more
|
|
||||||
on:
|
|
||||||
pull_request_target:
|
|
||||||
types: [synchronize, reopened, labeled]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
preview:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
# make sure the pull request is labeled with 'use-preview'
|
|
||||||
if: github.event.label.name == 'use-preview' || contains(github.event.pull_request.labels.*.name, 'use-preview')
|
|
||||||
env:
|
|
||||||
BASE: refs/pull/${{ github.event.pull_request.number }}/merge
|
|
||||||
REPO: ${{ github.event.repository.name }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
# Head commit of the pull request
|
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
|
||||||
path: pull
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: build
|
|
||||||
uses: ./.github/actions/build
|
|
||||||
with:
|
|
||||||
base: /${{ env.REPO }}/${{ env.BASE }}/
|
|
||||||
folder: pull
|
|
||||||
|
|
||||||
- name: publish preview
|
|
||||||
uses: JamesIves/github-pages-deploy-action@4.1.5
|
|
||||||
with:
|
|
||||||
folder: pull/dist
|
|
||||||
branch: build-previews
|
|
||||||
target-folder: ${{ env.BASE }}
|
|
||||||
single-commit: true
|
|
||||||
commit-message: "Publishing build result from #${{ github.event.pull_request.number }}"
|
|
||||||
|
|
||||||
- name: send comment
|
|
||||||
uses: marocchino/sticky-pull-request-comment@v2
|
|
||||||
with:
|
|
||||||
header: Preview environment
|
|
||||||
message: |
|
|
||||||
## Preview environment
|
|
||||||
https://${{ github.repository_owner }}.github.io/${{ env.REPO }}/${{ env.BASE }}/
|
|
||||||
|
|
||||||
This link will remain active until the `use-preview` label is removed.
|
|
||||||
128
.github/workflows/triage_pr.yml
vendored
128
.github/workflows/triage_pr.yml
vendored
@@ -1,72 +1,72 @@
|
|||||||
name: Add PR to Board
|
name: Add PR to Board
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request_target:
|
pull_request_target:
|
||||||
types: [opened]
|
types: [opened, synchronize, ready_for_review, review_requested]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
track_pr:
|
track_pr:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Get project data
|
- name: Get project data
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.PAT }}
|
GITHUB_TOKEN: ${{ secrets.PAT }}
|
||||||
run: |
|
run: |
|
||||||
gh api graphql -f query='
|
gh api graphql -f query='
|
||||||
query {
|
query {
|
||||||
organization(login: "revoltchat"){
|
organization(login: "revoltchat"){
|
||||||
projectNext(number: 3) {
|
projectNext(number: 3) {
|
||||||
id
|
id
|
||||||
fields(first:20) {
|
fields(first:20) {
|
||||||
nodes {
|
nodes {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
settings
|
settings
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}' > project_data.json
|
}' > project_data.json
|
||||||
|
|
||||||
echo 'PROJECT_ID='$(jq '.data.organization.projectNext.id' project_data.json) >> $GITHUB_ENV
|
echo 'PROJECT_ID='$(jq '.data.organization.projectNext.id' project_data.json) >> $GITHUB_ENV
|
||||||
echo 'STATUS_FIELD_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Status") | .id' project_data.json) >> $GITHUB_ENV
|
echo 'STATUS_FIELD_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Status") | .id' project_data.json) >> $GITHUB_ENV
|
||||||
echo 'INCOMING_OPTION_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Status") |.settings | fromjson.options[] | select(.name=="Incoming PRs") |.id' project_data.json) >> $GITHUB_ENV
|
echo 'INCOMING_OPTION_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Status") |.settings | fromjson.options[] | select(.name=="Incoming PRs") |.id' project_data.json) >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Add PR to project
|
- name: Add PR to project
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.PAT }}
|
GITHUB_TOKEN: ${{ secrets.PAT }}
|
||||||
PR_ID: ${{ github.event.pull_request.node_id }}
|
PR_ID: ${{ github.event.pull_request.node_id }}
|
||||||
run: |
|
run: |
|
||||||
item_id="$( gh api graphql -f query='
|
item_id="$( gh api graphql -f query='
|
||||||
mutation($project:ID!, $pr:ID!) {
|
mutation($project:ID!, $pr:ID!) {
|
||||||
addProjectNextItem(input: {projectId: $project, contentId: $pr}) {
|
addProjectNextItem(input: {projectId: $project, contentId: $pr}) {
|
||||||
projectNextItem {
|
projectNextItem {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}' -f project=$PROJECT_ID -f pr=$PR_ID --jq '.data.addProjectNextItem.projectNextItem.id')"
|
}' -f project=$PROJECT_ID -f pr=$PR_ID --jq '.data.addProjectNextItem.projectNextItem.id')"
|
||||||
|
|
||||||
echo 'ITEM_ID='$item_id >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Set fields
|
echo 'ITEM_ID='$item_id >> $GITHUB_ENV
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.PAT }}
|
- name: Set fields
|
||||||
run: |
|
env:
|
||||||
gh api graphql -f query='
|
GITHUB_TOKEN: ${{ secrets.PAT }}
|
||||||
mutation (
|
run: |
|
||||||
$project: ID!
|
gh api graphql -f query='
|
||||||
$item: ID!
|
mutation (
|
||||||
$status_field: ID!
|
$project: ID!
|
||||||
$status_value: String!
|
$item: ID!
|
||||||
) {
|
$status_field: ID!
|
||||||
set_status: updateProjectNextItemField(input: {
|
$status_value: String!
|
||||||
projectId: $project
|
) {
|
||||||
itemId: $item
|
set_status: updateProjectNextItemField(input: {
|
||||||
fieldId: $status_field
|
projectId: $project
|
||||||
value: $status_value
|
itemId: $item
|
||||||
}) {
|
fieldId: $status_field
|
||||||
projectNextItem {
|
value: $status_value
|
||||||
id
|
}) {
|
||||||
}
|
projectNextItem {
|
||||||
}
|
id
|
||||||
}' -f project=$PROJECT_ID -f item=$ITEM_ID -f status_field=$STATUS_FIELD_ID -f status_value=${{ env.INCOMING_OPTION_ID }} --silent
|
}
|
||||||
|
}
|
||||||
|
}' -f project=$PROJECT_ID -f item=$ITEM_ID -f status_field=$STATUS_FIELD_ID -f status_value=${{ env.INCOMING_OPTION_ID }} --silent
|
||||||
|
|||||||
1
.prettierignore
Normal file
1
.prettierignore
Normal file
@@ -0,0 +1 @@
|
|||||||
|
src/components/markdown/prism.ts
|
||||||
2
external/lang
vendored
2
external/lang
vendored
Submodule external/lang updated: 59fbe7c943...93ba149e7e
@@ -133,6 +133,7 @@
|
|||||||
"typescript": "^4.4.2",
|
"typescript": "^4.4.2",
|
||||||
"ulid": "^2.3.0",
|
"ulid": "^2.3.0",
|
||||||
"use-resize-observer": "^7.0.0",
|
"use-resize-observer": "^7.0.0",
|
||||||
|
"vite-plugin-compression": "^0.3.6",
|
||||||
"vite-plugin-pwa": "^0.8.1",
|
"vite-plugin-pwa": "^0.8.1",
|
||||||
"workbox-precaching": "^6.1.5"
|
"workbox-precaching": "^6.1.5"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import classNames from "classnames";
|
|||||||
import { attachContextMenu } from "preact-context-menu";
|
import { attachContextMenu } from "preact-context-menu";
|
||||||
import { useContext, useState } from "preact/hooks";
|
import { useContext, useState } from "preact/hooks";
|
||||||
|
|
||||||
import { useIntermediate } from "../../../../context/intermediate/Intermediate";
|
|
||||||
import { AppContext } from "../../../../context/revoltjs/RevoltClient";
|
import { AppContext } from "../../../../context/revoltjs/RevoltClient";
|
||||||
|
|
||||||
import AttachmentActions from "./AttachmentActions";
|
import AttachmentActions from "./AttachmentActions";
|
||||||
@@ -39,7 +38,7 @@ export default function Attachment({ attachment, hasContent }: Props) {
|
|||||||
width={metadata.width}
|
width={metadata.width}
|
||||||
height={metadata.height}
|
height={metadata.height}
|
||||||
onContextMenu={attachContextMenu("Menu", {
|
onContextMenu={attachContextMenu("Menu", {
|
||||||
attachment: attachment,
|
attachment,
|
||||||
})}
|
})}
|
||||||
className={classNames({
|
className={classNames({
|
||||||
[styles.margin]: hasContent,
|
[styles.margin]: hasContent,
|
||||||
|
|||||||
@@ -98,6 +98,12 @@ export const ReplyBase = styled.div<{
|
|||||||
transition: transform ease-in-out 0.1s;
|
transition: transform ease-in-out 0.1s;
|
||||||
filter: brightness(1);
|
filter: brightness(1);
|
||||||
|
|
||||||
|
> span > p {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
filter: brightness(2);
|
filter: brightness(2);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ import MarkdownEmoji from "markdown-it-emoji/dist/markdown-it-emoji-bare";
|
|||||||
import MarkdownSub from "markdown-it-sub";
|
import MarkdownSub from "markdown-it-sub";
|
||||||
// @ts-expect-error No typings.
|
// @ts-expect-error No typings.
|
||||||
import MarkdownSup from "markdown-it-sup";
|
import MarkdownSup from "markdown-it-sup";
|
||||||
import Prism from "prismjs";
|
|
||||||
import "prismjs/themes/prism-tomorrow.css";
|
|
||||||
import { RE_MENTIONS } from "revolt.js";
|
import { RE_MENTIONS } from "revolt.js";
|
||||||
|
|
||||||
import styles from "./Markdown.module.scss";
|
import styles from "./Markdown.module.scss";
|
||||||
@@ -26,6 +24,7 @@ import { generateEmoji } from "../common/Emoji";
|
|||||||
|
|
||||||
import { emojiDictionary } from "../../assets/emojis";
|
import { emojiDictionary } from "../../assets/emojis";
|
||||||
import { MarkdownProps } from "./Markdown";
|
import { MarkdownProps } from "./Markdown";
|
||||||
|
import Prism from "./prism";
|
||||||
|
|
||||||
// TODO: global.d.ts file for defining globals
|
// TODO: global.d.ts file for defining globals
|
||||||
declare global {
|
declare global {
|
||||||
|
|||||||
104
src/components/markdown/prism.ts
Normal file
104
src/components/markdown/prism.ts
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
// This file handles importing Prism code highlighting library.
|
||||||
|
|
||||||
|
import Prism from "prismjs";
|
||||||
|
|
||||||
|
// Default: markup, html, xml, svg, mathml, ssml, atom,
|
||||||
|
// rss, css, clike, javascript, js
|
||||||
|
|
||||||
|
import "prismjs/components/prism-c.min.js";
|
||||||
|
import "prismjs/components/prism-cpp.min.js";
|
||||||
|
import "prismjs/components/prism-csharp";
|
||||||
|
import "prismjs/components/prism-bash.min.js";
|
||||||
|
import "prismjs/components/prism-json.min.js";
|
||||||
|
import "prismjs/components/prism-json5.min.js";
|
||||||
|
import "prismjs/components/prism-typescript";
|
||||||
|
import "prismjs/components/prism-rust";
|
||||||
|
import "prismjs/components/prism-markdown";
|
||||||
|
import "prismjs/components/prism-brainfuck";
|
||||||
|
import "prismjs/components/prism-diff";
|
||||||
|
import "prismjs/components/prism-ruby";
|
||||||
|
import "prismjs/components/prism-go";
|
||||||
|
import "prismjs/components/prism-ini";
|
||||||
|
import "prismjs/components/prism-toml";
|
||||||
|
import "prismjs/components/prism-java";
|
||||||
|
import "prismjs/components/prism-kotlin";
|
||||||
|
import "prismjs/components/prism-less";
|
||||||
|
import "prismjs/components/prism-scss";
|
||||||
|
import "prismjs/components/prism-sass";
|
||||||
|
import "prismjs/components/prism-lua";
|
||||||
|
import "prismjs/components/prism-makefile";
|
||||||
|
import "prismjs/components/prism-perl";
|
||||||
|
import "prismjs/components/prism-objectivec";
|
||||||
|
import "prismjs/components/prism-python";
|
||||||
|
import "prismjs/components/prism-r";
|
||||||
|
import "prismjs/components/prism-sql";
|
||||||
|
import "prismjs/components/prism-graphql";
|
||||||
|
import "prismjs/components/prism-shell-session";
|
||||||
|
import "prismjs/components/prism-java";
|
||||||
|
import "prismjs/components/prism-powershell";
|
||||||
|
import "prismjs/components/prism-swift";
|
||||||
|
import "prismjs/components/prism-yaml";
|
||||||
|
import "prismjs/components/prism-visual-basic";
|
||||||
|
import "prismjs/components/prism-asm6502";
|
||||||
|
import "prismjs/components/prism-nasm";
|
||||||
|
import "prismjs/components/prism-wasm";
|
||||||
|
import "prismjs/components/prism-llvm";
|
||||||
|
import "prismjs/components/prism-apacheconf";
|
||||||
|
import "prismjs/components/prism-dns-zone-file";
|
||||||
|
import "prismjs/components/prism-docker";
|
||||||
|
import "prismjs/components/prism-nginx";
|
||||||
|
import "prismjs/components/prism-coq";
|
||||||
|
import "prismjs/components/prism-elixir";
|
||||||
|
import "prismjs/components/prism-elm";
|
||||||
|
import "prismjs/components/prism-erlang";
|
||||||
|
import "prismjs/components/prism-fsharp";
|
||||||
|
import "prismjs/components/prism-haskell";
|
||||||
|
import "prismjs/components/prism-ocaml";
|
||||||
|
import "prismjs/components/prism-reason";
|
||||||
|
import "prismjs/components/prism-scala";
|
||||||
|
import "prismjs/components/prism-sml";
|
||||||
|
import "prismjs/components/prism-xquery";
|
||||||
|
import "prismjs/components/prism-glsl";
|
||||||
|
import "prismjs/components/prism-mel";
|
||||||
|
import "prismjs/components/prism-processing";
|
||||||
|
import "prismjs/components/prism-clojure";
|
||||||
|
import "prismjs/components/prism-lisp";
|
||||||
|
import "prismjs/components/prism-scheme";
|
||||||
|
import "prismjs/components/prism-asciidoc";
|
||||||
|
import "prismjs/components/prism-latex";
|
||||||
|
import "prismjs/components/prism-http";
|
||||||
|
import "prismjs/components/prism-protobuf";
|
||||||
|
import "prismjs/components/prism-fortran";
|
||||||
|
import "prismjs/components/prism-wolfram";
|
||||||
|
import "prismjs/components/prism-matlab";
|
||||||
|
import "prismjs/components/prism-mizar";
|
||||||
|
import "prismjs/components/prism-stan";
|
||||||
|
import "prismjs/components/prism-jsstacktrace";
|
||||||
|
import "prismjs/components/prism-javastacktrace";
|
||||||
|
import "prismjs/components/prism-actionscript";
|
||||||
|
import "prismjs/components/prism-applescript";
|
||||||
|
import "prismjs/components/prism-autohotkey";
|
||||||
|
import "prismjs/components/prism-autoit";
|
||||||
|
import "prismjs/components/prism-coffeescript";
|
||||||
|
import "prismjs/components/prism-dart";
|
||||||
|
import "prismjs/components/prism-gml";
|
||||||
|
import "prismjs/components/prism-livescript";
|
||||||
|
import "prismjs/components/prism-moonscript";
|
||||||
|
import "prismjs/components/prism-qml";
|
||||||
|
import "prismjs/components/prism-vim";
|
||||||
|
import "prismjs/components/prism-nim";
|
||||||
|
import "prismjs/components/prism-swift";
|
||||||
|
import "prismjs/components/prism-haml";
|
||||||
|
import "prismjs/components/prism-ada";
|
||||||
|
import "prismjs/components/prism-arduino";
|
||||||
|
import "prismjs/components/prism-basic";
|
||||||
|
import "prismjs/components/prism-crystal";
|
||||||
|
import "prismjs/components/prism-batch";
|
||||||
|
import "prismjs/components/prism-excel-formula";
|
||||||
|
import "prismjs/components/prism-ebnf";
|
||||||
|
import "prismjs/components/prism-haxe";
|
||||||
|
import "prismjs/components/prism-mongodb";
|
||||||
|
|
||||||
|
import "prismjs/themes/prism-tomorrow.css";
|
||||||
|
|
||||||
|
export default Prism;
|
||||||
@@ -21,7 +21,7 @@ export default styled.button<Props>`
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 2px 16px;
|
padding: 2px 16px;
|
||||||
font-size: 0.875rem;
|
font-size: 0.8125rem;
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
|||||||
@@ -61,29 +61,63 @@ const ModalBase = styled.div`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ModalContainer = styled.div`
|
const ModalContainer = styled.div<
|
||||||
|
{
|
||||||
|
[key in "userProfile"]?: boolean;
|
||||||
|
}
|
||||||
|
>`
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
max-width: calc(100vw - 20px);
|
padding: 12px;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 440px;
|
||||||
border-radius: var(--border-radius);
|
border-radius: var(--border-radius);
|
||||||
|
|
||||||
animation-name: ${zoomIn};
|
animation-name: ${zoomIn};
|
||||||
animation-duration: 0.25s;
|
animation-duration: 0.25s;
|
||||||
animation-timing-function: cubic-bezier(0.3, 0.3, 0.18, 1.1);
|
animation-timing-function: cubic-bezier(0.3, 0.3, 0.18, 1.1);
|
||||||
|
|
||||||
|
${(props) =>
|
||||||
|
!props.userProfile &&
|
||||||
|
css`
|
||||||
|
max-width: max-content;
|
||||||
|
`}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ModalContent = styled.div<
|
const ModalContent = styled.div<
|
||||||
{ [key in "attachment" | "noBackground" | "border" | "padding"]?: boolean }
|
{
|
||||||
|
[key in
|
||||||
|
| "attachment"
|
||||||
|
| "noBackground"
|
||||||
|
| "border"
|
||||||
|
| "padding"
|
||||||
|
| "userProfile"]?: boolean;
|
||||||
|
}
|
||||||
>`
|
>`
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
border-radius: var(--border-radius);
|
border-radius: var(--border-radius);
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 14px;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
|
font-size: 14px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
form {
|
form {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
|
||||||
|
> div {
|
||||||
|
margin: 0;
|
||||||
|
color: var(--secondary-foreground);
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
${(props) =>
|
${(props) =>
|
||||||
@@ -95,7 +129,7 @@ const ModalContent = styled.div<
|
|||||||
${(props) =>
|
${(props) =>
|
||||||
props.padding &&
|
props.padding &&
|
||||||
css`
|
css`
|
||||||
padding: 1.5em;
|
padding: 1rem;
|
||||||
`}
|
`}
|
||||||
|
|
||||||
${(props) =>
|
${(props) =>
|
||||||
@@ -117,7 +151,7 @@ const ModalActions = styled.div`
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
|
|
||||||
padding: 1em 1.5em;
|
padding: 1rem;
|
||||||
background: var(--secondary-background);
|
background: var(--secondary-background);
|
||||||
border-radius: 0 0 var(--border-radius) var(--border-radius);
|
border-radius: 0 0 var(--border-radius) var(--border-radius);
|
||||||
`;
|
`;
|
||||||
@@ -131,6 +165,7 @@ interface Props {
|
|||||||
children?: Children;
|
children?: Children;
|
||||||
title?: Children;
|
title?: Children;
|
||||||
|
|
||||||
|
userProfile?: boolean;
|
||||||
disallowClosing?: boolean;
|
disallowClosing?: boolean;
|
||||||
noBackground?: boolean;
|
noBackground?: boolean;
|
||||||
dontModal?: boolean;
|
dontModal?: boolean;
|
||||||
@@ -152,6 +187,7 @@ export default function Modal(props: Props) {
|
|||||||
<ModalContent
|
<ModalContent
|
||||||
attachment={!!props.actions}
|
attachment={!!props.actions}
|
||||||
noBackground={props.noBackground}
|
noBackground={props.noBackground}
|
||||||
|
userProfile={props.userProfile}
|
||||||
border={props.border}
|
border={props.border}
|
||||||
padding={props.padding ?? !props.dontModal}>
|
padding={props.padding ?? !props.dontModal}>
|
||||||
{props.title && <h3>{props.title}</h3>}
|
{props.title && <h3>{props.title}</h3>}
|
||||||
@@ -209,7 +245,9 @@ export default function Modal(props: Props) {
|
|||||||
<ModalBase
|
<ModalBase
|
||||||
className={animateClose ? "closing" : undefined}
|
className={animateClose ? "closing" : undefined}
|
||||||
onClick={(!props.disallowClosing && props.onClose) || undefined}>
|
onClick={(!props.disallowClosing && props.onClose) || undefined}>
|
||||||
<ModalContainer onClick={(e) => (e.cancelBubble = true)}>
|
<ModalContainer
|
||||||
|
onClick={(e) => (e.cancelBubble = true)}
|
||||||
|
userProfile={false}>
|
||||||
{content}
|
{content}
|
||||||
{props.actions && (
|
{props.actions && (
|
||||||
<ModalActions>
|
<ModalActions>
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
import { ChevronRight, LinkExternal } from "@styled-icons/boxicons-regular";
|
import {
|
||||||
|
ChevronRight,
|
||||||
|
LinkExternal,
|
||||||
|
Pencil,
|
||||||
|
} from "@styled-icons/boxicons-regular";
|
||||||
import styled, { css } from "styled-components";
|
import styled, { css } from "styled-components";
|
||||||
|
|
||||||
import { Children } from "../../../types/Preact";
|
import { Children } from "../../../types/Preact";
|
||||||
@@ -11,7 +15,6 @@ interface BaseProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const CategoryBase = styled.div<BaseProps>`
|
const CategoryBase = styled.div<BaseProps>`
|
||||||
/*height: 54px;*/
|
|
||||||
padding: 9.8px 12px;
|
padding: 9.8px 12px;
|
||||||
border-radius: var(--border-radius);
|
border-radius: var(--border-radius);
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
@@ -21,6 +24,7 @@ const CategoryBase = styled.div<BaseProps>`
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
> svg {
|
> svg {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
@@ -142,7 +146,6 @@ export default function CategoryButton({
|
|||||||
{icon}
|
{icon}
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div className="title">{children}</div>
|
<div className="title">{children}</div>
|
||||||
|
|
||||||
<div className="description">{description}</div>
|
<div className="description">{description}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="action">
|
<div class="action">
|
||||||
|
|||||||
@@ -123,29 +123,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.botStats {
|
|
||||||
background: var(--secondary-background);
|
|
||||||
border-radius: var(--border-radius);
|
|
||||||
padding: 10px;
|
|
||||||
|
|
||||||
font-size: 12px;
|
|
||||||
|
|
||||||
.stat {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 5px;
|
|
||||||
opacity: 0.5;
|
|
||||||
|
|
||||||
&:nth-child(1) {
|
|
||||||
opacity: 1;
|
|
||||||
|
|
||||||
> svg {
|
|
||||||
color: var(--accent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
> span {
|
> span {
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
@@ -175,10 +152,6 @@
|
|||||||
border-radius: var(--border-radius);
|
border-radius: var(--border-radius);
|
||||||
background-color: var(--secondary-background);
|
background-color: var(--secondary-background);
|
||||||
|
|
||||||
.info {
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: var(--primary-background);
|
background-color: var(--primary-background);
|
||||||
}
|
}
|
||||||
@@ -194,19 +167,5 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.botContainer {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 8px;
|
|
||||||
margin-bottom: 18px;
|
|
||||||
|
|
||||||
.owner {
|
|
||||||
text-transform: uppercase;
|
|
||||||
font-size: 10px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,10 @@
|
|||||||
import {
|
import { ListUl } from "@styled-icons/boxicons-regular";
|
||||||
ListUl,
|
|
||||||
DotsVerticalRounded,
|
|
||||||
ChevronRight,
|
|
||||||
} from "@styled-icons/boxicons-regular";
|
|
||||||
import {
|
import {
|
||||||
Envelope,
|
Envelope,
|
||||||
Edit,
|
Edit,
|
||||||
UserPlus,
|
UserPlus,
|
||||||
Group,
|
Group,
|
||||||
InfoCircle,
|
InfoCircle,
|
||||||
BadgeCheck,
|
|
||||||
Cog,
|
|
||||||
TimeFive,
|
|
||||||
} from "@styled-icons/boxicons-solid";
|
} from "@styled-icons/boxicons-solid";
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { Link, useHistory } from "react-router-dom";
|
import { Link, useHistory } from "react-router-dom";
|
||||||
@@ -164,6 +157,7 @@ export const UserProfile = observer(
|
|||||||
backgroundImage:
|
backgroundImage:
|
||||||
backgroundURL &&
|
backgroundURL &&
|
||||||
`linear-gradient( rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0.7) ), url('${backgroundURL}')`,
|
`linear-gradient( rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0.7) ), url('${backgroundURL}')`,
|
||||||
|
paddingBottom: "1px",
|
||||||
}}>
|
}}>
|
||||||
<div className={styles.profile}>
|
<div className={styles.profile}>
|
||||||
<UserIcon
|
<UserIcon
|
||||||
@@ -240,9 +234,6 @@ export const UserProfile = observer(
|
|||||||
<UserPlus size={28} />
|
<UserPlus size={28} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
)}
|
)}
|
||||||
{/*<IconButton onClick={() => user.addFriend()}>
|
|
||||||
<DotsVerticalRounded size={26} />
|
|
||||||
</IconButton>*/}
|
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.tabs}>
|
<div className={styles.tabs}>
|
||||||
<div
|
<div
|
||||||
@@ -297,59 +288,31 @@ export const UserProfile = observer(
|
|||||||
{user.bot ? (
|
{user.bot ? (
|
||||||
<>
|
<>
|
||||||
<div className={styles.category}>
|
<div className={styles.category}>
|
||||||
Bot information
|
bot owner
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.botContainer}>
|
<div
|
||||||
<div className={styles.botStats}>
|
onClick={() =>
|
||||||
<div className={styles.stat}>
|
user.bot &&
|
||||||
<BadgeCheck size="15" />
|
openScreen({
|
||||||
<b>
|
id: "profile",
|
||||||
This bot has been
|
user_id: user.bot.owner,
|
||||||
officially verified by
|
})
|
||||||
Revolt
|
}
|
||||||
</b>
|
className={styles.entry}
|
||||||
</div>
|
key={user.bot.owner}>
|
||||||
<div className={styles.stat}>
|
<UserIcon
|
||||||
<Cog size="15" />
|
size={32}
|
||||||
Used in <b>456 servers</b>
|
target={client.users.get(
|
||||||
</div>
|
user.bot.owner,
|
||||||
<div className={styles.stat}>
|
)}
|
||||||
<TimeFive size="14" />
|
/>
|
||||||
Bot active since{" "}
|
<span>
|
||||||
<b>Apr 15, 2019</b>
|
<Username
|
||||||
</div>
|
user={client.users.get(
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
onClick={() =>
|
|
||||||
user.bot &&
|
|
||||||
openScreen({
|
|
||||||
id: "profile",
|
|
||||||
user_id: user.bot.owner,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
className={styles.entry}
|
|
||||||
key={user.bot.owner}>
|
|
||||||
<UserIcon
|
|
||||||
size={32}
|
|
||||||
target={client.users.get(
|
|
||||||
user.bot.owner,
|
user.bot.owner,
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<div className={styles.info}>
|
</span>
|
||||||
<Username
|
|
||||||
user={client.users.get(
|
|
||||||
user.bot.owner,
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
className={
|
|
||||||
styles.owner
|
|
||||||
}>
|
|
||||||
Bot owner
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<ChevronRight size="24" />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
|
|||||||
@@ -72,6 +72,7 @@
|
|||||||
|
|
||||||
.small {
|
.small {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
color: var(--tertiary-foreground);
|
color: var(--tertiary-foreground);
|
||||||
|
|||||||
@@ -20,33 +20,39 @@ type BehaviourType =
|
|||||||
| { behaviour: "ask"; onChange: (file: File) => void }
|
| { behaviour: "ask"; onChange: (file: File) => void }
|
||||||
| { behaviour: "upload"; onUpload: (id: string) => Promise<void> }
|
| { behaviour: "upload"; onUpload: (id: string) => Promise<void> }
|
||||||
| {
|
| {
|
||||||
behaviour: "multi";
|
behaviour: "multi";
|
||||||
onChange: (files: File[]) => void;
|
onChange: (files: File[]) => void;
|
||||||
append?: (files: File[]) => void;
|
append?: (files: File[]) => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
type StyleType =
|
type StyleType =
|
||||||
| {
|
| {
|
||||||
style: "icon" | "banner";
|
style: "icon" | "banner";
|
||||||
width?: number;
|
width?: number;
|
||||||
height?: number;
|
height?: number;
|
||||||
previewURL?: string;
|
previewURL?: string;
|
||||||
defaultPreview?: string;
|
defaultPreview?: string;
|
||||||
desaturateDefault?: boolean
|
desaturateDefault?: boolean;
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
style: "attachment";
|
style: "attachment";
|
||||||
attached: boolean;
|
attached: boolean;
|
||||||
uploading: boolean;
|
uploading: boolean;
|
||||||
cancel: () => void;
|
cancel: () => void;
|
||||||
size?: number;
|
size?: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
type Props = BehaviourType & StyleType & {
|
type Props = BehaviourType &
|
||||||
fileType: "backgrounds" | "icons" | "avatars" | "attachments" | "banners";
|
StyleType & {
|
||||||
maxFileSize: number;
|
fileType:
|
||||||
remove: () => Promise<void>;
|
| "backgrounds"
|
||||||
}
|
| "icons"
|
||||||
|
| "avatars"
|
||||||
|
| "attachments"
|
||||||
|
| "banners";
|
||||||
|
maxFileSize: number;
|
||||||
|
remove: () => Promise<void>;
|
||||||
|
};
|
||||||
|
|
||||||
export async function uploadFile(
|
export async function uploadFile(
|
||||||
autumnURL: string,
|
autumnURL: string,
|
||||||
@@ -226,14 +232,19 @@ export function FileUploader(props: Props) {
|
|||||||
})}
|
})}
|
||||||
data-uploading={uploading}>
|
data-uploading={uploading}>
|
||||||
<div
|
<div
|
||||||
className={classNames(styles.image, props.desaturateDefault && previewURL == null && styles.desaturate)}
|
className={classNames(
|
||||||
|
styles.image,
|
||||||
|
props.desaturateDefault &&
|
||||||
|
previewURL == null &&
|
||||||
|
styles.desaturate,
|
||||||
|
)}
|
||||||
style={{
|
style={{
|
||||||
backgroundImage:
|
backgroundImage:
|
||||||
style === "icon"
|
style === "icon"
|
||||||
? `url('${previewURL ?? defaultPreview}')`
|
? `url('${previewURL ?? defaultPreview}')`
|
||||||
: previewURL
|
: previewURL
|
||||||
? `linear-gradient( rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5) ), url('${previewURL}')`
|
? `linear-gradient( rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5) ), url('${previewURL}')`
|
||||||
: "none",
|
: "none",
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -63,22 +63,24 @@ function Notifier({ options, notifs }: Props) {
|
|||||||
playSound("message");
|
playSound("message");
|
||||||
if (!showNotification) return;
|
if (!showNotification) return;
|
||||||
|
|
||||||
|
const effectiveName = msg.masquerade?.name ?? msg.author?.username;
|
||||||
|
|
||||||
let title;
|
let title;
|
||||||
switch (msg.channel?.channel_type) {
|
switch (msg.channel?.channel_type) {
|
||||||
case "SavedMessages":
|
case "SavedMessages":
|
||||||
return;
|
return;
|
||||||
case "DirectMessage":
|
case "DirectMessage":
|
||||||
title = `@${msg.author?.username}`;
|
title = `@${effectiveName}`;
|
||||||
break;
|
break;
|
||||||
case "Group":
|
case "Group":
|
||||||
if (msg.author?._id === "00000000000000000000000000") {
|
if (msg.author?._id === "00000000000000000000000000") {
|
||||||
title = msg.channel.name;
|
title = msg.channel.name;
|
||||||
} else {
|
} else {
|
||||||
title = `@${msg.author?.username} - ${msg.channel.name}`;
|
title = `@${effectiveName} - ${msg.channel.name}`;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "TextChannel":
|
case "TextChannel":
|
||||||
title = `@${msg.author?.username} (#${msg.channel.name}, ${msg.channel.server?.name})`;
|
title = `@${effectiveName} (#${msg.channel.name}, ${msg.channel.server?.name})`;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
title = msg.channel?._id;
|
title = msg.channel?._id;
|
||||||
@@ -100,7 +102,12 @@ function Notifier({ options, notifs }: Props) {
|
|||||||
let body, icon;
|
let body, icon;
|
||||||
if (typeof msg.content === "string") {
|
if (typeof msg.content === "string") {
|
||||||
body = client.markdownToText(msg.content);
|
body = client.markdownToText(msg.content);
|
||||||
icon = msg.author?.generateAvatarURL({ max_side: 256 });
|
|
||||||
|
if (msg.masquerade?.avatar) {
|
||||||
|
icon = client.proxyFile(msg.masquerade.avatar);
|
||||||
|
} else {
|
||||||
|
icon = msg.author?.generateAvatarURL({ max_side: 256 });
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const users = client.users;
|
const users = client.users;
|
||||||
switch (msg.content.type) {
|
switch (msg.content.type) {
|
||||||
|
|||||||
@@ -1,28 +1,53 @@
|
|||||||
.home {
|
.home {
|
||||||
|
height: 100%;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
h3 {
|
.homeScreen {
|
||||||
margin: 1em 0;
|
|
||||||
font-size: 48px;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
img {
|
|
||||||
height: 36px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.actions {
|
|
||||||
gap: 8px;
|
|
||||||
width: 236px;
|
|
||||||
|
|
||||||
margin: auto;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
width: fit-content;
|
|
||||||
align-items: stretch;
|
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 95%;
|
||||||
|
padding: 12px;
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin: 20px 0;
|
||||||
|
font-size: 48px;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 36px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
width: 100%;
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions {
|
||||||
|
//grid-template-columns: repeat(2, 300px);
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||||||
|
grid-column: span 2;
|
||||||
|
gap: 16px;
|
||||||
|
//margin: auto;
|
||||||
|
display: grid;
|
||||||
|
width: fit-content;
|
||||||
|
align-items: stretch;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
a {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
&:nth-child(4) {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,20 @@
|
|||||||
import { Home as HomeIcon } from "@styled-icons/boxicons-solid";
|
import { Money } from "@styled-icons/boxicons-regular";
|
||||||
|
import {
|
||||||
|
Home as HomeIcon,
|
||||||
|
PlusCircle,
|
||||||
|
Compass,
|
||||||
|
Megaphone,
|
||||||
|
Group,
|
||||||
|
Cog,
|
||||||
|
RightArrowCircle,
|
||||||
|
} from "@styled-icons/boxicons-solid";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import styled, { css } from "styled-components";
|
import styled, { css } from "styled-components";
|
||||||
|
|
||||||
import styles from "./Home.module.scss";
|
import styles from "./Home.module.scss";
|
||||||
|
import "./snow.scss";
|
||||||
import { Text } from "preact-i18n";
|
import { Text } from "preact-i18n";
|
||||||
import { useContext, useState } from "preact/hooks";
|
import { useContext, useMemo, useState } from "preact/hooks";
|
||||||
|
|
||||||
import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice";
|
import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice";
|
||||||
|
|
||||||
@@ -32,6 +42,19 @@ const IconConainer = styled.div`
|
|||||||
`}
|
`}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const Overlay = styled.div`
|
||||||
|
display: grid;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
> * {
|
||||||
|
grid-area: 1 / 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
const client = useContext(AppContext);
|
const client = useContext(AppContext);
|
||||||
const [showChannels, setChannels] = useState(
|
const [showChannels, setChannels] = useState(
|
||||||
@@ -59,68 +82,140 @@ export default function Home() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const snowflakes = useMemo(() => {
|
||||||
|
const flakes = [];
|
||||||
|
|
||||||
|
// Disable outside of December
|
||||||
|
if (new Date().getMonth() !== 11) return [];
|
||||||
|
|
||||||
|
for (let i = 0; i < 15; i++) {
|
||||||
|
flakes.push("❄️");
|
||||||
|
flakes.push("❄");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < 2; i++) {
|
||||||
|
flakes.push("🎄");
|
||||||
|
flakes.push("☃️");
|
||||||
|
flakes.push("⛄");
|
||||||
|
}
|
||||||
|
|
||||||
|
return flakes;
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.home}>
|
<div className={styles.home}>
|
||||||
<Header placement="primary">
|
<Overlay>
|
||||||
<IconConainer onClick={toggleChannelSidebar}>
|
<div class="snowfall">
|
||||||
<HomeIcon size={24} />
|
{snowflakes.map((emoji, index) => (
|
||||||
</IconConainer>
|
<div key={index} class="snowflake">
|
||||||
<Text id="app.navigation.tabs.home" />
|
{emoji}
|
||||||
</Header>
|
</div>
|
||||||
<h3>
|
))}
|
||||||
<Text id="app.special.modals.onboarding.welcome" />
|
</div>
|
||||||
<br />
|
<div className="content">
|
||||||
<img src={wideSVG} />
|
<Header placement="primary">
|
||||||
</h3>
|
<IconConainer onClick={toggleChannelSidebar}>
|
||||||
<div className={styles.actions}>
|
<HomeIcon size={24} />
|
||||||
<Link to="/invite/Testers">
|
</IconConainer>
|
||||||
<CategoryButton
|
<Text id="app.navigation.tabs.home" />
|
||||||
action="chevron"
|
</Header>
|
||||||
icon={<Emoji emoji="😁" size={32} />}>
|
<div className={styles.homeScreen}>
|
||||||
{client.servers.get("01F7ZSBSFHQ8TA81725KQCSDDP") ? (
|
<h3>
|
||||||
<Text id="app.home.goto-testers" />
|
<Text id="app.special.modals.onboarding.welcome" />
|
||||||
) : (
|
<br />
|
||||||
<Text id="app.home.join-testers" />
|
<img src={wideSVG} />
|
||||||
)}
|
</h3>
|
||||||
</CategoryButton>
|
<div className={styles.actions}>
|
||||||
</Link>
|
<Link to="/settings">
|
||||||
<a
|
<CategoryButton
|
||||||
href="https://insrt.uk/donate"
|
action="chevron"
|
||||||
target="_blank"
|
icon={<PlusCircle size={32} />}
|
||||||
rel="noreferrer">
|
description={
|
||||||
<CategoryButton
|
"Invite all of your friends, some cool bots, and throw a big party."
|
||||||
action="external"
|
}>
|
||||||
icon={<Emoji emoji="💷" size={32} />}>
|
Create a group
|
||||||
<Text id="app.home.donate" />
|
</CategoryButton>
|
||||||
</CategoryButton>
|
</Link>
|
||||||
</a>
|
<a
|
||||||
<Link to="/settings/feedback">
|
href="https://revolt.social"
|
||||||
<CategoryButton
|
target="_blank"
|
||||||
action="chevron"
|
rel="noreferrer">
|
||||||
icon={<Emoji emoji="🎉" size={32} />}>
|
<CategoryButton
|
||||||
<Text id="app.home.feedback" />
|
action="external"
|
||||||
</CategoryButton>
|
icon={<Compass size={32} />}
|
||||||
</Link>
|
description={
|
||||||
<a
|
"Find a community based on your hobbies or interests."
|
||||||
href="https://revolt.social"
|
}>
|
||||||
target="_blank"
|
Join a community
|
||||||
rel="noreferrer">
|
</CategoryButton>
|
||||||
<CategoryButton
|
</a>
|
||||||
action="external"
|
|
||||||
icon={<Emoji emoji="🧭" size={32} />}>
|
{client.servers.get(
|
||||||
<Text id="app.home.social" />
|
"01F7ZSBSFHQ8TA81725KQCSDDP",
|
||||||
</CategoryButton>
|
) ? (
|
||||||
</a>
|
<Link to="/server/01F7ZSBSFHQ8TA81725KQCSDDP">
|
||||||
<Tooltip content={<Text id="app.home.settings-tooltip" />}>
|
<CategoryButton
|
||||||
<Link to="/settings">
|
action="chevron"
|
||||||
<CategoryButton
|
icon={<RightArrowCircle size={32} />}
|
||||||
action="chevron"
|
description={
|
||||||
icon={<Emoji emoji="🔧" size={32} />}>
|
"You can report issues and discuss improvements with us directly here."
|
||||||
<Text id="app.home.settings" />
|
}>
|
||||||
</CategoryButton>
|
<Text id="app.home.goto-testers" />
|
||||||
</Link>
|
</CategoryButton>
|
||||||
</Tooltip>
|
</Link>
|
||||||
</div>
|
) : (
|
||||||
|
<Link to="/invite/Testers">
|
||||||
|
<CategoryButton
|
||||||
|
action="chevron"
|
||||||
|
icon={<Group size={32} />}
|
||||||
|
description={
|
||||||
|
"You can report issues and discuss improvements with us directly here."
|
||||||
|
}>
|
||||||
|
<Text id="app.home.join-testers" />
|
||||||
|
</CategoryButton>
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Link to="/settings/feedback">
|
||||||
|
<CategoryButton
|
||||||
|
action="chevron"
|
||||||
|
icon={<Megaphone size={32} />}
|
||||||
|
description={
|
||||||
|
"Let us know how we can improve our app by giving us feedback."
|
||||||
|
}>
|
||||||
|
<Text id="app.home.feedback" />
|
||||||
|
</CategoryButton>
|
||||||
|
</Link>
|
||||||
|
<a
|
||||||
|
href="https://insrt.uk/donate"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer">
|
||||||
|
<CategoryButton
|
||||||
|
action="external"
|
||||||
|
icon={<Money size={32} />}>
|
||||||
|
<Text id="app.home.donate" />
|
||||||
|
</CategoryButton>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<Tooltip
|
||||||
|
content={
|
||||||
|
<Text id="app.home.settings-tooltip" />
|
||||||
|
}>
|
||||||
|
<Link to="/settings">
|
||||||
|
<CategoryButton
|
||||||
|
action="chevron"
|
||||||
|
icon={<Cog size={32} />}>
|
||||||
|
<Text id="app.home.settings" />
|
||||||
|
</CategoryButton>
|
||||||
|
</Link>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
<Link to="/settings/appearance">
|
||||||
|
<a>Turn off homescreen effects</a>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Overlay>{" "}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
91
src/pages/home/snow.scss
Normal file
91
src/pages/home/snow.scss
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
// Pure CSS Snowfall
|
||||||
|
// Released by Artimon under MIT license
|
||||||
|
//
|
||||||
|
// Source: https://github.com/Artimon/pure-css-snowfall
|
||||||
|
|
||||||
|
$count: 36;
|
||||||
|
$screenOffset: 0px;
|
||||||
|
$fallDuration: 12;
|
||||||
|
$windNoise: 30;
|
||||||
|
$windSpeed: 4;
|
||||||
|
$sizeNoise: 40;
|
||||||
|
$rotation: 360;
|
||||||
|
$imageSize: 20px;
|
||||||
|
$fontSize: 40px;
|
||||||
|
|
||||||
|
.snowfall {
|
||||||
|
z-index: 0;
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
font-size: $fontSize;
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
pointer-events: none;
|
||||||
|
|
||||||
|
.snowflake {
|
||||||
|
position: relative;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
width: $screenOffset;
|
||||||
|
height: $screenOffset;
|
||||||
|
|
||||||
|
span {
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
align-self: center;
|
||||||
|
width: $imageSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@while ($count > 0) {
|
||||||
|
$left: random(100);
|
||||||
|
$deltaLeft: random(2 * $windNoise * 10) / 10 - $windNoise + $windSpeed;
|
||||||
|
$scale: 1 + (random(2 * $sizeNoise * 10) / 10 - $sizeNoise) / 100;
|
||||||
|
|
||||||
|
.snowflake:nth-child(#{$count}) {
|
||||||
|
animation: animation-snowflake-#{$count} linear infinite;
|
||||||
|
animation-duration: $fallDuration +
|
||||||
|
random($fallDuration * 10) /
|
||||||
|
10 +
|
||||||
|
s;
|
||||||
|
animation-delay: random(2 * $fallDuration * 10) /
|
||||||
|
10 -
|
||||||
|
(2 * $fallDuration) +
|
||||||
|
s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes animation-snowflake-#{$count} {
|
||||||
|
0% {
|
||||||
|
left: percentage($left / 100);
|
||||||
|
top: calc(0% - #{$screenOffset});
|
||||||
|
transform: scale($scale)
|
||||||
|
rotate3d(
|
||||||
|
random(100) / 100,
|
||||||
|
random(100) / 100,
|
||||||
|
random(100) / 100,
|
||||||
|
0deg
|
||||||
|
);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
left: percentage(($left + $deltaLeft) / 100);
|
||||||
|
top: calc(100% + #{$screenOffset});
|
||||||
|
transform: scale($scale)
|
||||||
|
rotate3d(
|
||||||
|
random(100) / 100,
|
||||||
|
random(100) / 100,
|
||||||
|
random(100) / 100,
|
||||||
|
(random($rotation) + $rotation) *
|
||||||
|
((random(2) - 1) * 2 - 1) + deg
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$count: $count - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -193,7 +193,9 @@
|
|||||||
padding: 80px 32px;
|
padding: 80px 32px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: fit-content;
|
|
||||||
|
// This prevents members, invites and ban list from being able to properly display.
|
||||||
|
// height: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
details {
|
details {
|
||||||
@@ -242,6 +244,10 @@
|
|||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
|
||||||
|
> a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
h6 {
|
h6 {
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import {
|
|||||||
OperationsContext,
|
OperationsContext,
|
||||||
} from "../../context/revoltjs/RevoltClient";
|
} from "../../context/revoltjs/RevoltClient";
|
||||||
|
|
||||||
|
import UserIcon from "../../components/common/user/UserIcon";
|
||||||
import LineDivider from "../../components/ui/LineDivider";
|
import LineDivider from "../../components/ui/LineDivider";
|
||||||
|
|
||||||
import ButtonItem from "../../components/navigation/items/ButtonItem";
|
import ButtonItem from "../../components/navigation/items/ButtonItem";
|
||||||
@@ -54,7 +55,15 @@ import { Sessions } from "./panes/Sessions";
|
|||||||
import { Sync } from "./panes/Sync";
|
import { Sync } from "./panes/Sync";
|
||||||
import { ThemeShop } from "./panes/ThemeShop";
|
import { ThemeShop } from "./panes/ThemeShop";
|
||||||
|
|
||||||
const IndexHeader = styled.div``;
|
const IndexHeader = styled.div`
|
||||||
|
/*display: flex;*/
|
||||||
|
background: var(--secondary-background);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
padding: 20px;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
display: none;
|
||||||
|
`;
|
||||||
|
|
||||||
export default function Settings() {
|
export default function Settings() {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
@@ -261,7 +270,12 @@ export default function Settings() {
|
|||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
indexHeader={<IndexHeader>{/**/}</IndexHeader>}
|
indexHeader={
|
||||||
|
<IndexHeader>
|
||||||
|
<UserIcon size={64} />
|
||||||
|
Username
|
||||||
|
</IndexHeader>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { At, Key, Block } from "@styled-icons/boxicons-regular";
|
import { At, Key, Block, ListOl } from "@styled-icons/boxicons-regular";
|
||||||
import {
|
import {
|
||||||
Envelope,
|
Envelope,
|
||||||
HelpCircle,
|
HelpCircle,
|
||||||
@@ -165,6 +165,7 @@ export const Account = observer(() => {
|
|||||||
</CategoryButton>
|
</CategoryButton>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
<hr />
|
||||||
<h3>
|
<h3>
|
||||||
<Text id="app.settings.pages.account.2fa.title" />
|
<Text id="app.settings.pages.account.2fa.title" />
|
||||||
</h3>
|
</h3>
|
||||||
@@ -184,9 +185,17 @@ export const Account = observer(() => {
|
|||||||
icon={<Lock size={24} color="var(--error)" />}
|
icon={<Lock size={24} color="var(--error)" />}
|
||||||
description={"Set up 2FA on your account."}
|
description={"Set up 2FA on your account."}
|
||||||
disabled
|
disabled
|
||||||
action="chevron">
|
action={<Text id="general.unavailable" />}>
|
||||||
Set up Two-factor authentication
|
Set up Two-factor authentication
|
||||||
</CategoryButton>
|
</CategoryButton>
|
||||||
|
{/*<CategoryButton
|
||||||
|
icon={<ListOl size={24} />}
|
||||||
|
description={"View and download your 2FA backup codes."}
|
||||||
|
disabled
|
||||||
|
action="chevron">
|
||||||
|
View my backup codes
|
||||||
|
</CategoryButton>*/}
|
||||||
|
<hr />
|
||||||
<h3>
|
<h3>
|
||||||
<Text id="app.settings.pages.account.manage.title" />
|
<Text id="app.settings.pages.account.manage.title" />
|
||||||
</h3>
|
</h3>
|
||||||
|
|||||||
@@ -165,6 +165,20 @@ export function Component(props: Props) {
|
|||||||
</h3>
|
</h3>
|
||||||
<ColourSwatches value={theme.accent} onChange={setAccent} />
|
<ColourSwatches value={theme.accent} onChange={setAccent} />
|
||||||
|
|
||||||
|
{/* TOFIX: Chane this checkbox to turn off the seasonal home page animations*/}
|
||||||
|
<Checkbox
|
||||||
|
checked={props.settings.theme?.ligatures === true}
|
||||||
|
onChange={() =>
|
||||||
|
setTheme({
|
||||||
|
ligatures: !props.settings.theme?.ligatures,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
description={
|
||||||
|
"Displays effects in the home tab during holiday seasons."
|
||||||
|
}>
|
||||||
|
Seasonal theme
|
||||||
|
</Checkbox>
|
||||||
|
|
||||||
{/*<h3>
|
{/*<h3>
|
||||||
<Text id="app.settings.pages.appearance.message_display" />
|
<Text id="app.settings.pages.appearance.message_display" />
|
||||||
</h3>
|
</h3>
|
||||||
|
|||||||
@@ -149,11 +149,21 @@
|
|||||||
|
|
||||||
.badgePicker {
|
.badgePicker {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 10px;
|
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
//padding-bottom: 8px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
overflow-x: auto;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.check {
|
.check {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
|
flex-shrink: 0;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
width: 50px;
|
width: 50px;
|
||||||
background: var(--secondary-background);
|
background: var(--secondary-background);
|
||||||
@@ -173,9 +183,41 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TOFIX: need to merge overlay 1 and 2 later
|
||||||
|
|
||||||
|
.overlay {
|
||||||
|
position: absolute;
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 8px;
|
||||||
|
background: red;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
background: linear-gradient(
|
||||||
|
to right,
|
||||||
|
var(--primary-background),
|
||||||
|
transparent
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay2 {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 8px;
|
||||||
|
background: red;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
background: linear-gradient(
|
||||||
|
to left,
|
||||||
|
var(--primary-background),
|
||||||
|
transparent
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
.row {
|
.row {
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
|
||||||
.pfp {
|
.pfp {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -74,10 +74,15 @@ export const Profile = observer(() => {
|
|||||||
</div>
|
</div>
|
||||||
{/*<h3>Badges</h3>
|
{/*<h3>Badges</h3>
|
||||||
<div className={styles.badgePicker}>
|
<div className={styles.badgePicker}>
|
||||||
<div className={styles.check}>a</div>
|
<div className={styles.overlay} />
|
||||||
<div className={styles.check}>b</div>
|
<div className={styles.container}>
|
||||||
<div className={styles.check}>c</div>
|
<div className={styles.check}>a</div>
|
||||||
|
<div className={styles.check}>b</div>
|
||||||
|
<div className={styles.check}>c</div>
|
||||||
|
</div>
|
||||||
|
<div className={styles.overlay2} />
|
||||||
</div>*/}
|
</div>*/}
|
||||||
|
<hr />
|
||||||
<div className={styles.row}>
|
<div className={styles.row}>
|
||||||
<div className={styles.pfp}>
|
<div className={styles.pfp}>
|
||||||
<h3>
|
<h3>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Chrome, Android, Apple, Windows } from "@styled-icons/boxicons-logos";
|
import { Chrome, Android, Apple, Windows } from "@styled-icons/boxicons-logos";
|
||||||
import { HelpCircle, Desktop } from "@styled-icons/boxicons-regular";
|
import { HelpCircle, Desktop, LogOut } from "@styled-icons/boxicons-regular";
|
||||||
import {
|
import {
|
||||||
Safari,
|
Safari,
|
||||||
Firefoxbrowser,
|
Firefoxbrowser,
|
||||||
@@ -24,6 +24,7 @@ import { AppContext } from "../../../context/revoltjs/RevoltClient";
|
|||||||
import Button from "../../../components/ui/Button";
|
import Button from "../../../components/ui/Button";
|
||||||
import Preloader from "../../../components/ui/Preloader";
|
import Preloader from "../../../components/ui/Preloader";
|
||||||
import Tip from "../../../components/ui/Tip";
|
import Tip from "../../../components/ui/Tip";
|
||||||
|
import CategoryButton from "../../../components/ui/fluent/CategoryButton";
|
||||||
|
|
||||||
dayjs.extend(relativeTime);
|
dayjs.extend(relativeTime);
|
||||||
|
|
||||||
@@ -207,7 +208,7 @@ export function Sessions() {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
<Button
|
{/*<Button
|
||||||
error
|
error
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
// ! FIXME: add to rAuth
|
// ! FIXME: add to rAuth
|
||||||
@@ -230,7 +231,37 @@ export function Sessions() {
|
|||||||
setSessions(sessions.filter((x) => x._id === deviceId));
|
setSessions(sessions.filter((x) => x._id === deviceId));
|
||||||
}}>
|
}}>
|
||||||
<Text id="app.settings.pages.sessions.logout" />
|
<Text id="app.settings.pages.sessions.logout" />
|
||||||
</Button>
|
</Button>*/}
|
||||||
|
<hr />
|
||||||
|
<CategoryButton
|
||||||
|
onClick={async () => {
|
||||||
|
// ! FIXME: add to rAuth
|
||||||
|
const del: string[] = [];
|
||||||
|
render.forEach((session) => {
|
||||||
|
if (deviceId !== session._id) {
|
||||||
|
del.push(session._id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
setDelete(del);
|
||||||
|
|
||||||
|
for (const id of del) {
|
||||||
|
await client.req(
|
||||||
|
"DELETE",
|
||||||
|
`/auth/session/${id}` as "/auth/session/id",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
setSessions(sessions.filter((x) => x._id === deviceId));
|
||||||
|
}}
|
||||||
|
icon={<LogOut size={24} color={"var(--error)"} />}
|
||||||
|
action={"chevron"}
|
||||||
|
description={
|
||||||
|
"Logs you out of all sessions except this device."
|
||||||
|
}>
|
||||||
|
<Text id="app.settings.pages.sessions.logout" />
|
||||||
|
</CategoryButton>
|
||||||
|
|
||||||
<Tip>
|
<Tip>
|
||||||
<span>
|
<span>
|
||||||
<Text id="app.settings.tips.sessions.a" />
|
<Text id="app.settings.tips.sessions.a" />
|
||||||
|
|||||||
@@ -296,6 +296,7 @@ export function ThemeShop() {
|
|||||||
<Tip warning hideSeparator>
|
<Tip warning hideSeparator>
|
||||||
The Theme Shop is currently under construction.
|
The Theme Shop is currently under construction.
|
||||||
</Tip>
|
</Tip>
|
||||||
|
<hr />
|
||||||
{/* FIXME INTEGRATE WITH MOBX */}
|
{/* FIXME INTEGRATE WITH MOBX */}
|
||||||
{/*<ActiveTheme>
|
{/*<ActiveTheme>
|
||||||
<div class="active-indicator">
|
<div class="active-indicator">
|
||||||
|
|||||||
@@ -49,6 +49,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
border-radius: var(--border-radius);
|
||||||
background: var(--secondary-background);
|
background: var(--secondary-background);
|
||||||
|
|
||||||
span,
|
span,
|
||||||
@@ -76,6 +77,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.invite {
|
||||||
|
}
|
||||||
|
|
||||||
.member {
|
.member {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
@@ -95,12 +99,18 @@
|
|||||||
|
|
||||||
.virtual {
|
.virtual {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
> div > div > div {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.roles {
|
.roles {
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
height: 100%;
|
height: auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
.list {
|
.list {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import replace from "@rollup/plugin-replace";
|
|||||||
import { readFileSync } from "fs";
|
import { readFileSync } from "fs";
|
||||||
import { resolve } from "path";
|
import { resolve } from "path";
|
||||||
import { defineConfig } from "vite";
|
import { defineConfig } from "vite";
|
||||||
|
import viteCompression from "vite-plugin-compression";
|
||||||
import { VitePWA } from "vite-plugin-pwa";
|
import { VitePWA } from "vite-plugin-pwa";
|
||||||
|
|
||||||
import preact from "@preact/preset-vite";
|
import preact from "@preact/preset-vite";
|
||||||
@@ -42,6 +43,10 @@ function getVersion() {
|
|||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [
|
plugins: [
|
||||||
|
viteCompression({
|
||||||
|
verbose: true,
|
||||||
|
algorithm: "brotliCompress",
|
||||||
|
}),
|
||||||
preact(),
|
preact(),
|
||||||
VitePWA({
|
VitePWA({
|
||||||
srcDir: "src",
|
srcDir: "src",
|
||||||
|
|||||||
11
yarn.lock
11
yarn.lock
@@ -1877,7 +1877,7 @@ chalk@^2.0.0:
|
|||||||
escape-string-regexp "^1.0.5"
|
escape-string-regexp "^1.0.5"
|
||||||
supports-color "^5.3.0"
|
supports-color "^5.3.0"
|
||||||
|
|
||||||
chalk@^4.0.0:
|
chalk@^4.0.0, chalk@^4.1.2:
|
||||||
version "4.1.2"
|
version "4.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
|
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
|
||||||
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
|
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
|
||||||
@@ -4317,6 +4317,15 @@ value-equal@^1.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c"
|
resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c"
|
||||||
integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==
|
integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==
|
||||||
|
|
||||||
|
vite-plugin-compression@^0.3.6:
|
||||||
|
version "0.3.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/vite-plugin-compression/-/vite-plugin-compression-0.3.6.tgz#85e3ce5047ae6747bc3952177177a852fac901be"
|
||||||
|
integrity sha512-aSskQCJsP3VQ8PsnY+vO7UfD5qoFMOEuzg0PG2E9Zqyx+ARmc3wr9KCgOFraZOFW1Y4UAa5BR0SMTjoxHRMJoQ==
|
||||||
|
dependencies:
|
||||||
|
chalk "^4.1.2"
|
||||||
|
debug "^4.3.2"
|
||||||
|
fs-extra "^10.0.0"
|
||||||
|
|
||||||
vite-plugin-pwa@^0.8.1:
|
vite-plugin-pwa@^0.8.1:
|
||||||
version "0.8.2"
|
version "0.8.2"
|
||||||
resolved "https://registry.yarnpkg.com/vite-plugin-pwa/-/vite-plugin-pwa-0.8.2.tgz#2789a157e2f71faf834d968945efc22eee9ad64a"
|
resolved "https://registry.yarnpkg.com/vite-plugin-pwa/-/vite-plugin-pwa-0.8.2.tgz#2789a157e2f71faf834d968945efc22eee9ad64a"
|
||||||
|
|||||||
Reference in New Issue
Block a user