12 Commits

49 changed files with 3725 additions and 11887 deletions

View File

@ -1 +1 @@
FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:18 FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:20

View File

@ -3,19 +3,22 @@
"dockerComposeFile": "./docker-compose.yml", "dockerComposeFile": "./docker-compose.yml",
"service": "workspace", "service": "workspace",
"workspaceFolder": "/workspace", "workspaceFolder": "/workspace",
"settings": { "customizations": {
"remote.autoForwardPorts": false "vscode": {
"settings": {
"remote.autoForwardPorts": false,
"remote.localPortHost": "allInterfaces"
},
"extensions": [
"editorconfig.editorconfig",
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"bradlc.vscode-tailwindcss",
"mikestead.dotenv",
"davidanson.vscode-markdownlint",
"ms-azuretools.vscode-docker"
]
}
}, },
"extensions": [
"editorconfig.editorconfig",
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"bradlc.vscode-tailwindcss",
"mikestead.dotenv",
"davidanson.vscode-markdownlint",
"ms-azuretools.vscode-docker"
],
"forwardPorts": [3000],
"postAttachCommand": ["npm", "install"],
"remoteUser": "node" "remoteUser": "node"
} }

View File

@ -6,3 +6,4 @@ services:
volumes: volumes:
- '..:/workspace:cached' - '..:/workspace:cached'
command: 'sleep infinity' command: 'sleep infinity'
network_mode: 'host'

View File

@ -1,5 +1,4 @@
.*
!.npmrc
build build
.next
coverage coverage
node_modules node_modules

View File

@ -4,12 +4,14 @@
"parserOptions": { "parserOptions": {
"project": "./tsconfig.json" "project": "./tsconfig.json"
}, },
"env": {
"node": true,
"browser": true
},
"rules": { "rules": {
"prettier/prettier": "error", "prettier/prettier": "error",
"@next/next/no-img-element": "off" "@next/next/no-img-element": "off"
} },
"overrides": [
{
"files": ["*.ts", "*.tsx"],
"parser": "@typescript-eslint/parser"
}
]
} }

View File

@ -1,6 +1,6 @@
<!-- Please first discuss the change you wish to make via issue before making a change. It might avoid a waste of your time. --> <!-- Please first discuss the change you wish to make via issue before making a change. It might avoid a waste of your time. -->
## What changes this PR introduce? # What changes this PR introduce?
## List any relevant issue numbers ## List any relevant issue numbers

View File

@ -16,7 +16,7 @@ jobs:
language: ['javascript'] language: ['javascript']
steps: steps:
- uses: 'actions/checkout@v3.5.0' - uses: 'actions/checkout@v3.5.3'
- name: 'Initialize CodeQL' - name: 'Initialize CodeQL'
uses: 'github/codeql-action/init@v2' uses: 'github/codeql-action/init@v2'

View File

@ -10,16 +10,16 @@ jobs:
build: build:
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
steps: steps:
- uses: 'actions/checkout@v3.5.0' - uses: 'actions/checkout@v3.5.3'
- name: 'Use Node.js' - name: 'Setup Node.js'
uses: 'actions/setup-node@v3.6.0' uses: 'actions/setup-node@v3.6.0'
with: with:
node-version: '18.x' node-version: '20.x'
cache: 'npm' cache: 'npm'
- name: 'Install' - name: 'Install dependencies'
run: 'npm install' run: 'npm clean-install'
- name: 'Build' - name: 'Build'
run: 'npm run build' run: 'npm run build'

View File

@ -10,16 +10,16 @@ jobs:
lint: lint:
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
steps: steps:
- uses: 'actions/checkout@v3.5.0' - uses: 'actions/checkout@v3.5.3'
- name: 'Use Node.js' - name: 'Setup Node.js'
uses: 'actions/setup-node@v3.6.0' uses: 'actions/setup-node@v3.6.0'
with: with:
node-version: '18.x' node-version: '20.x'
cache: 'npm' cache: 'npm'
- name: 'Install' - name: 'Install dependencies'
run: 'npm install' run: 'npm clean-install'
- name: 'lint:commit' - name: 'lint:commit'
run: 'npm run lint:commit -- --to "${{ github.sha }}"' run: 'npm run lint:commit -- --to "${{ github.sha }}"'
@ -35,8 +35,3 @@ jobs:
- name: 'lint:prettier' - name: 'lint:prettier'
run: 'npm run lint:prettier' run: 'npm run lint:prettier'
- name: 'lint:dotenv'
uses: 'dotenv-linter/action-dotenv-linter@v2'
with:
github_token: ${{ secrets.github_token }}

View File

@ -8,26 +8,26 @@ jobs:
release: release:
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
steps: steps:
- uses: 'actions/checkout@v3.5.0' - uses: 'actions/checkout@v3.5.3'
with: with:
fetch-depth: 0 fetch-depth: 0
persist-credentials: false persist-credentials: false
- name: 'Import GPG key' - name: 'Import GPG key'
uses: 'crazy-max/ghaction-import-gpg@v4' uses: 'crazy-max/ghaction-import-gpg@v5.3.0'
with: with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
git_user_signingkey: true git_user_signingkey: true
git_commit_gpgsign: true git_commit_gpgsign: true
- name: 'Use Node.js' - name: 'Setup Node.js'
uses: 'actions/setup-node@v3.6.0' uses: 'actions/setup-node@v3.6.0'
with: with:
node-version: '18.x' node-version: '20.x'
cache: 'npm' cache: 'npm'
- name: 'Install' - name: 'Install dependencies'
run: 'npm install' run: 'npm clean-install'
- name: 'Release' - name: 'Release'
run: 'npm run release' run: 'npm run release'
@ -35,10 +35,3 @@ jobs:
GH_TOKEN: ${{ secrets.GH_TOKEN }} GH_TOKEN: ${{ secrets.GH_TOKEN }}
GIT_COMMITTER_NAME: ${{ secrets.GIT_NAME }} GIT_COMMITTER_NAME: ${{ secrets.GIT_NAME }}
GIT_COMMITTER_EMAIL: ${{ secrets.GIT_EMAIL }} GIT_COMMITTER_EMAIL: ${{ secrets.GIT_EMAIL }}
- name: 'Deploy to Vercel'
run: 'npm run deploy -- --token="${VERCEL_TOKEN}" --prod'
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}

View File

@ -10,33 +10,33 @@ jobs:
test-unit: test-unit:
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
steps: steps:
- uses: 'actions/checkout@v3.5.0' - uses: 'actions/checkout@v3.5.3'
- name: 'Use Node.js' - name: 'Setup Node.js'
uses: 'actions/setup-node@v3.6.0' uses: 'actions/setup-node@v3.6.0'
with: with:
node-version: '18.x' node-version: '20.x'
cache: 'npm' cache: 'npm'
- name: 'Install' - name: 'Install dependencies'
run: 'npm install' run: 'npm clean-install'
- name: 'Unit Test' - name: 'Unit Test'
run: 'npm run test:unit' run: 'npm run test:unit'
test-lighthouse: test-e2e:
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
steps: steps:
- uses: 'actions/checkout@v3.5.0' - uses: 'actions/checkout@v3.5.3'
- name: 'Use Node.js' - name: 'Setup Node.js'
uses: 'actions/setup-node@v3.6.0' uses: 'actions/setup-node@v3.6.0'
with: with:
node-version: '18.x' node-version: '20.x'
cache: 'npm' cache: 'npm'
- name: 'Install' - name: 'Install dependencies'
run: 'npm install' run: 'npm clean-install'
- name: 'Build' - name: 'Build'
run: 'npm run build' run: 'npm run build'
@ -44,27 +44,5 @@ jobs:
- name: 'html-w3c-validator' - name: 'html-w3c-validator'
run: 'npm run test:html-w3c-validator' run: 'npm run test:html-w3c-validator'
- name: 'Lighthouse'
run: 'npm run test:lighthouse'
env:
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
test-e2e:
runs-on: 'ubuntu-latest'
steps:
- uses: 'actions/checkout@v3.5.0'
- name: 'Use Node.js'
uses: 'actions/setup-node@v3.6.0'
with:
node-version: '18.x'
cache: 'npm'
- name: 'Install'
run: 'npm install'
- name: 'Build'
run: 'npm run build'
- name: 'End To End (e2e) Test' - name: 'End To End (e2e) Test'
run: 'npm run test:e2e' run: 'npm run test:e2e'

6
.gitignore vendored
View File

@ -18,10 +18,6 @@ cypress/screenshots
cypress/videos cypress/videos
cypress/downloads cypress/downloads
# PWA
**/workbox-*.js
**/sw.js
# envs # envs
.env .env
.env.production .env.production
@ -47,8 +43,6 @@ npm-debug.log*
# misc # misc
.DS_Store .DS_Store
.lighthouseci
.vercel
*.hbs *.hbs
# typescript # typescript

View File

@ -1,31 +0,0 @@
{
"ci": {
"collect": {
"startServerCommand": "npm run start",
"startServerReadyPattern": "ready on",
"startServerReadyTimeout": 20000,
"url": [
"http://127.0.0.1:3000/",
"http://127.0.0.1:3000/authentication/forgot-password",
"http://127.0.0.1:3000/authentication/reset-password",
"http://127.0.0.1:3000/authentication/signin",
"http://127.0.0.1:3000/authentication/signup"
],
"numberOfRuns": 1
},
"assert": {
"preset": "lighthouse:recommended",
"assertions": {
"image-size-responsive": "warning",
"unsized-images": "warning",
"csp-xss": "warning",
"non-composited-animations": "warning",
"unused-javascript": "warning"
}
},
"upload": {
"target": "temporary-public-storage"
},
"server": {}
}
}

View File

@ -1,4 +1,10 @@
{ {
"config": {
"extends": "markdownlint/style/prettier",
"relative-links": true,
"default": true,
"MD033": false
},
"globs": ["**/*.{md,mdx}"], "globs": ["**/*.{md,mdx}"],
"ignores": ["**/node_modules"], "ignores": ["**/node_modules"],
"customRules": ["markdownlint-rule-relative-links"] "customRules": ["markdownlint-rule-relative-links"]

View File

@ -1,7 +0,0 @@
{
"default": true,
"relative-links": true,
"extends": "markdownlint/style/prettier",
"MD033": false,
"MD041": false
}

View File

@ -60,7 +60,7 @@ representative at an online or offline event.
Instances of abusive, harassing, or otherwise unacceptable behavior may be Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at reported to the community leaders responsible for enforcement at
contact@divlo.fr. <contact@theoludwig.fr>.
All complaints will be reviewed and investigated promptly and fairly. All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the All community leaders are obligated to respect the privacy and security of the

View File

@ -30,31 +30,7 @@ If you're adding new features to **Thream/website**, please include tests.
## Commits ## Commits
The commit message guidelines respect The commit message guidelines adheres to [Conventional Commits](https://www.conventionalcommits.org/) and [Semantic Versioning](https://semver.org/) for releases.
[@commitlint/config-conventional](https://github.com/conventional-changelog/commitlint/tree/master/%40commitlint/config-conventional)
and [Semantic Versioning](https://semver.org/) for releases.
### Types
Types define which kind of changes you made to the project.
| Types | Description |
| -------- | ------------------------------------------------------------------------------------------------------------ |
| feat | A new feature. |
| fix | A bug fix. |
| docs | Documentation only changes. |
| style | Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc). |
| refactor | A code change that neither fixes a bug nor adds a feature. |
| perf | A code change that improves performance. |
| test | Adding missing tests or correcting existing tests. |
| build | Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm). |
| ci | Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs). |
| chore | Other changes that don't modify src or test files. |
| revert | Reverts a previous commit. |
### Scopes
Scopes define what part of the code changed.
### Examples ### Examples
@ -67,10 +43,10 @@ git commit -m "docs(readme): update installation process"
[Reference issue](https://github.com/Thream/website/issues/24) [Reference issue](https://github.com/Thream/website/issues/24)
Feel free to contribute to Thream and add new languages, we would appreciate your help! Feel free to contribute to **Thream** and add new languages, we would appreciate your help!
To add a new language: To add a new language:
- `npm install` - `npm clean-install`
- `npm run generate` - `npm run generate`
- Start editing JSON files with the translation in `locales/{{locale}}` (e.g: `locales/en`) - Start editing JSON files with the translation in `locales/{{locale}}` (e.g: `locales/en`)

View File

@ -1,15 +1,16 @@
FROM node:18.15.0 AS builder-dependencies FROM node:20.5.0 AS builder-dependencies
WORKDIR /usr/src/application WORKDIR /usr/src/application
COPY ./.npmrc ./
COPY ./package*.json ./ COPY ./package*.json ./
RUN npm install RUN npm clean-install
FROM node:18.15.0 AS builder FROM node:20.5.0 AS builder
WORKDIR /usr/src/application WORKDIR /usr/src/application
COPY --from=builder-dependencies /usr/src/application/node_modules ./node_modules COPY --from=builder-dependencies /usr/src/application/node_modules ./node_modules
COPY ./ ./ COPY ./ ./
RUN npm run build RUN npm run build
FROM gcr.io/distroless/nodejs18-debian11:latest AS runner FROM gcr.io/distroless/nodejs20-debian11:latest AS runner
WORKDIR /usr/src/application WORKDIR /usr/src/application
ENV NODE_ENV=production ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1 ENV NEXT_TELEMETRY_DISABLED=1

View File

@ -1,4 +1,4 @@
<h1 align="center"><a href="https://thream.divlo.fr/">Thream/website</a></h1> <h1 align="center"><a href="https://thream.theoludwig.fr/">Thream/website</a></h1>
<p align="center"> <p align="center">
<a href="./CONTRIBUTING.md"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat" /></a> <a href="./CONTRIBUTING.md"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat" /></a>
@ -18,7 +18,7 @@
Thream's website to stay close with your friends and communities. Thream's website to stay close with your friends and communities.
It uses [Thream/api](https://github.com/Thream/api) [v1.2.5](https://github.com/Thream/api/releases/tag/v1.2.5). It uses [Thream/api](https://github.com/Thream/api) [v1.2.8](https://github.com/Thream/api/releases/tag/v1.2.8).
## ⚙️ Getting Started ## ⚙️ Getting Started
@ -31,7 +31,7 @@ It uses [Thream/api](https://github.com/Thream/api) [v1.2.5](https://github.com/
```sh ```sh
# Clone the repository # Clone the repository
git clone https://github.com/Thream/website.git git clone git@github.com:Thream/website.git
# Go to the project root # Go to the project root
cd website cd website
@ -40,7 +40,7 @@ cd website
cp .env.example .env cp .env.example .env
# Install # Install
npm install npm clean-install
``` ```
You will need to configure the environment variables by creating an `.env` file at You will need to configure the environment variables by creating an `.env` file at
@ -61,7 +61,7 @@ docker compose up --build
#### Services started #### Services started
- website : `http://127.0.0.1:3000` - `website`: <http://127.0.0.1:3000>
## 💡 Contributing ## 💡 Contributing

View File

@ -87,7 +87,11 @@ export const GuildSettings: React.FC = () => {
const formData = new FormData() const formData = new FormData()
formData.append('icon', file) formData.append('icon', file)
try { try {
await authentication.api.put(`/guilds/${guild.id}/icon`, formData) await authentication.api.put(`/guilds/${guild.id}/icon`, formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
setFetchState('idle') setFetchState('idle')
} catch (error) { } catch (error) {
setFetchState('error') setFetchState('error')

View File

@ -50,7 +50,8 @@ export const MessageText: React.FC<MessageContentProps> = (props) => {
) )
}, },
emoji: (props) => { emoji: (props) => {
return <Emoji value={props.value} size={20} tooltip /> const { value } = props
return <Emoji value={value} size={20} tooltip />
}, },
code: (properties) => { code: (properties) => {
const { inline, className, children, ...props } = properties const { inline, className, children, ...props } = properties

View File

@ -60,7 +60,12 @@ export const SendMessage: React.FC<SendMessageProps> = (props) => {
formData.append('file', file) formData.append('file', file)
await authentication.api.post( await authentication.api.post(
`/channels/${path.channelId}/messages/uploads`, `/channels/${path.channelId}/messages/uploads`,
formData formData,
{
headers: {
'Content-Type': 'multipart/form-data'
}
}
) )
} }
} }

View File

@ -156,7 +156,12 @@ export const UserSettings: React.FC = () => {
try { try {
const { data } = await authentication.api.put( const { data } = await authentication.api.put(
`/users/current/logo`, `/users/current/logo`,
formData formData,
{
headers: {
'Content-Type': 'multipart/form-data'
}
}
) )
setUser((oldUser) => { setUser((oldUser) => {
return { return {

View File

@ -13,9 +13,9 @@ export const Head: React.FC<HeadProps> = (props) => {
const { const {
title = 'Thream', title = 'Thream',
image = 'https://thream.divlo.fr/images/icons/128x128.png', image = 'https://thream.theoludwig.fr/images/icon-128x128.png',
description = t('common:description'), description = t('common:description'),
url = 'https://thream.divlo.fr/' url = 'https://thream.theoludwig.fr/'
} = props } = props
return ( return (
@ -26,7 +26,7 @@ export const Head: React.FC<HeadProps> = (props) => {
{/* Meta Tag */} {/* Meta Tag */}
<meta name='viewport' content='width=device-width, initial-scale=1.0' /> <meta name='viewport' content='width=device-width, initial-scale=1.0' />
<meta name='description' content={description} /> <meta name='description' content={description} />
<meta name='Language' content='fr, en' /> <meta name='Language' content='fr-FR, en-US' />
<meta name='theme-color' content='#27B05E' /> <meta name='theme-color' content='#27B05E' />
{/* Open Graph Metadata */} {/* Open Graph Metadata */}
@ -35,7 +35,7 @@ export const Head: React.FC<HeadProps> = (props) => {
<meta property='og:url' content={url} /> <meta property='og:url' content={url} />
<meta property='og:image' content={image} /> <meta property='og:image' content={image} />
<meta property='og:description' content={description} /> <meta property='og:description' content={description} />
<meta property='og:locale' content='fr_FR, en_US' /> <meta property='og:locale' content='fr-FR, en-US' />
<meta property='og:site_name' content={title} /> <meta property='og:site_name' content={title} />
{/* Twitter card Metadata */} {/* Twitter card Metadata */}
@ -43,12 +43,6 @@ export const Head: React.FC<HeadProps> = (props) => {
<meta name='twitter:description' content={description} /> <meta name='twitter:description' content={description} />
<meta name='twitter:title' content={title} /> <meta name='twitter:title' content={title} />
<meta name='twitter:image' content={image} /> <meta name='twitter:image' content={image} />
{/* PWA Data */}
<link rel='manifest' href='/manifest.json' />
<meta name='apple-mobile-web-app-capable' content='yes' />
<meta name='mobile-web-app-capable' content='yes' />
<link rel='apple-touch-icon' href={image} />
</NextHead> </NextHead>
) )
} }

View File

@ -15,7 +15,7 @@ export const Header: React.FC = () => {
quality={100} quality={100}
width={60} width={60}
height={60} height={60}
src='/images/icons/Thream.png' src='/images/Thream.png'
alt='Thream' alt='Thream'
/> />
<span className='ml-1 hidden font-headline font-medium text-green-800 dark:text-green-400 xs:block'> <span className='ml-1 hidden font-headline font-medium text-green-800 dark:text-green-400 xs:block'>

View File

@ -7,10 +7,10 @@ export interface LoaderProps {
} }
export const Loader: React.FC<LoaderProps> = (props) => { export const Loader: React.FC<LoaderProps> = (props) => {
const { width = 50, height = 50 } = props const { width = 50, height = 50, className } = props
return ( return (
<div className={props.className}> <div className={className}>
<div <div
data-cy='progress-spinner' data-cy='progress-spinner'
className='relative mx-auto my-0 before:block before:pt-[100%] before:content-none' className='relative mx-auto my-0 before:block before:pt-[100%] before:content-none'

View File

@ -29,7 +29,7 @@ export default defineConfig({
server = getLocal({ cors: true }) server = getLocal({ cors: true })
await server.start(API_DEFAULT_PORT) await server.start(API_DEFAULT_PORT)
for (const handler of handlers) { for (const handler of handlers) {
const { isFile = false } = handler.response const { isFile = false, statusCode, body } = handler.response
let requestBuilder = server.forGet(handler.url) let requestBuilder = server.forGet(handler.url)
switch (handler.method) { switch (handler.method) {
case 'GET': case 'GET':
@ -47,14 +47,11 @@ export default defineConfig({
} }
if (isFile) { if (isFile) {
await requestBuilder.thenFromFile( await requestBuilder.thenFromFile(
handler.response.statusCode, statusCode,
path.join(UPLOADS_FIXTURES_DIRECTORY, ...handler.response.body) path.join(UPLOADS_FIXTURES_DIRECTORY, ...body)
) )
} else { } else {
await requestBuilder.thenJson( await requestBuilder.thenJson(statusCode, body)
handler.response.statusCode,
handler.response.body
)
} }
} }

View File

@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@ -2,10 +2,10 @@ services:
thream-website: thream-website:
container_name: ${COMPOSE_PROJECT_NAME} container_name: ${COMPOSE_PROJECT_NAME}
image: 'thream-website' image: 'thream-website'
restart: 'unless-stopped'
build: build:
context: './' context: './'
ports: network_mode: 'host'
- '${PORT-3000}:${PORT-3000}'
environment: environment:
PORT: ${PORT-3000} PORT: ${PORT-3000}
env_file: './.env' env_file: '.env'

View File

@ -1,7 +1,3 @@
const nextPWA = require('next-pwa')({
disable: process.env.NODE_ENV !== 'production',
dest: 'public'
})
const nextTranslate = require('next-translate-plugin') const nextTranslate = require('next-translate-plugin')
/** @type {import("next").NextConfig} */ /** @type {import("next").NextConfig} */
@ -10,11 +6,11 @@ const nextConfig = {
output: 'standalone', output: 'standalone',
images: { images: {
domains: [ domains: [
'api.thream.divlo.fr', 'api.thream.theoludwig.fr',
'file-uploads-api.thream.divlo.fr', 'file-uploads-api.thream.theoludwig.fr',
...(process.env.NODE_ENV !== 'production' ? ['127.0.0.1'] : []) ...(process.env.NODE_ENV !== 'production' ? ['127.0.0.1'] : [])
] ]
} }
} }
module.exports = nextTranslate(nextPWA(nextConfig)) module.exports = nextTranslate(nextConfig)

15121
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{ {
"name": "@thream/website", "name": "@thream/website",
"version": "1.3.3", "version": "1.3.8",
"private": true, "private": true,
"repository": { "repository": {
"type": "git", "type": "git",
@ -14,102 +14,96 @@
"dev": "next dev", "dev": "next dev",
"start": "next start", "start": "next start",
"build": "next build", "build": "next build",
"export": "next export",
"generate": "plop", "generate": "plop",
"lint:commit": "commitlint", "lint:commit": "commitlint",
"lint:editorconfig": "editorconfig-checker", "lint:editorconfig": "editorconfig-checker",
"lint:markdown": "markdownlint-cli2", "lint:markdown": "markdownlint-cli2",
"lint:eslint": "eslint \".\" --ignore-path \".gitignore\"", "lint:eslint": "eslint . --max-warnings 0 --report-unused-disable-directives --ignore-path .gitignore",
"lint:prettier": "prettier \".\" --check --ignore-path \".gitignore\"", "lint:prettier": "prettier . --check",
"lint:staged": "lint-staged", "lint:staged": "lint-staged",
"test:unit": "cypress run --component", "test:unit": "cypress run --component",
"test:html-w3c-validator": "start-server-and-test \"start\" \"http://127.0.0.1:3000\" \"html-w3c-validator\"", "test:html-w3c-validator": "start-server-and-test \"start\" \"http://127.0.0.1:3000\" \"html-w3c-validator\"",
"test:lighthouse": "lhci autorun",
"test:e2e": "start-server-and-test \"start\" \"http://127.0.0.1:3000\" \"cypress run\"", "test:e2e": "start-server-and-test \"start\" \"http://127.0.0.1:3000\" \"cypress run\"",
"test:dev": "start-server-and-test \"dev\" \"http://127.0.0.1:3000\" \"cypress open\"", "test:dev": "start-server-and-test \"dev\" \"http://127.0.0.1:3000\" \"cypress open\"",
"release": "semantic-release", "release": "semantic-release",
"deploy": "vercel",
"postinstall": "husky install" "postinstall": "husky install"
}, },
"dependencies": { "dependencies": {
"@fontsource/montserrat": "4.5.14", "@fontsource/montserrat": "5.0.5",
"@fontsource/roboto": "4.5.8", "@fontsource/roboto": "5.0.5",
"@heroicons/react": "1.0.6", "@heroicons/react": "1.0.6",
"@sinclair/typebox": "0.26.8", "@sinclair/typebox": "0.29.6",
"@thream/socketio-jwt": "3.0.4", "@thream/socketio-jwt": "3.1.2",
"axios": "1.3.4", "axios": "1.4.0",
"clsx": "1.2.1", "clsx": "2.0.0",
"date-and-time": "2.4.3", "date-and-time": "3.0.2",
"emoji-mart": "3.0.1", "emoji-mart": "3.0.1",
"katex": "0.16.4", "katex": "0.16.8",
"next": "13.2.4", "next": "13.4.7",
"next-pwa": "5.6.0",
"next-themes": "0.2.1", "next-themes": "0.2.1",
"next-translate": "2.0.4", "next-translate": "2.4.4",
"pretty-bytes": "6.1.0", "pretty-bytes": "6.1.1",
"react": "18.2.0", "react": "18.2.0",
"react-component-form": "4.0.0", "react-component-form": "4.1.1",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"react-infinite-scroll-component": "6.1.0", "react-infinite-scroll-component": "6.1.0",
"react-markdown": "8.0.6", "react-markdown": "8.0.7",
"react-responsive": "9.0.2", "react-responsive": "9.0.2",
"react-swipeable": "7.0.0", "react-swipeable": "7.0.1",
"react-syntax-highlighter": "15.5.0", "react-syntax-highlighter": "15.5.0",
"react-textarea-autosize": "8.4.1", "react-textarea-autosize": "8.5.2",
"read-pkg": "7.1.0", "read-pkg": "8.0.0",
"rehype-katex": "6.0.2", "rehype-katex": "6.0.3",
"remark-breaks": "3.0.2", "remark-breaks": "3.0.3",
"remark-gfm": "3.0.1", "remark-gfm": "3.0.1",
"remark-math": "5.1.1", "remark-math": "5.1.1",
"sharp": "0.32.0", "sharp": "0.32.4",
"socket.io-client": "4.6.1", "socket.io-client": "4.7.1",
"unified": "10.1.2", "unified": "10.1.2",
"unist-util-visit": "4.1.2", "unist-util-visit": "4.1.2",
"universal-cookie": "4.0.4" "universal-cookie": "4.0.4"
}, },
"devDependencies": { "devDependencies": {
"@commitlint/cli": "17.5.1", "@commitlint/cli": "17.6.7",
"@commitlint/config-conventional": "17.4.4", "@commitlint/config-conventional": "17.6.7",
"@lhci/cli": "0.11.0", "@saithodev/semantic-release-backmerge": "3.2.0",
"@saithodev/semantic-release-backmerge": "3.1.0",
"@semantic-release/git": "10.0.1", "@semantic-release/git": "10.0.1",
"@tsconfig/strictest": "2.0.0", "@tsconfig/strictest": "2.0.1",
"@types/emoji-mart": "3.0.9", "@types/emoji-mart": "3.0.9",
"@types/hast": "2.3.4", "@types/hast": "2.3.4",
"@types/katex": "0.16.0", "@types/katex": "0.16.1",
"@types/node": "18.15.11", "@types/node": "20.4.4",
"@types/react": "18.0.32", "@types/react": "18.2.15",
"@types/react-responsive": "8.0.5", "@types/react-responsive": "8.0.5",
"@types/react-syntax-highlighter": "15.5.6", "@types/react-syntax-highlighter": "15.5.7",
"@types/unist": "2.0.6", "@types/unist": "2.0.6",
"@typescript-eslint/eslint-plugin": "5.57.0", "@typescript-eslint/eslint-plugin": "6.1.0",
"@typescript-eslint/parser": "5.57.0", "@typescript-eslint/parser": "6.1.0",
"autoprefixer": "10.4.14", "autoprefixer": "10.4.14",
"cypress": "12.9.0", "cypress": "12.17.2",
"editorconfig-checker": "5.0.1", "editorconfig-checker": "5.1.1",
"eslint": "8.37.0", "eslint": "8.45.0",
"eslint-config-conventions": "8.0.0", "eslint-config-conventions": "11.0.1",
"eslint-config-next": "13.2.4", "eslint-config-next": "13.4.7",
"eslint-config-prettier": "8.8.0", "eslint-config-prettier": "8.8.0",
"eslint-plugin-import": "2.27.5", "eslint-plugin-import": "2.27.5",
"eslint-plugin-prettier": "4.2.1", "eslint-plugin-prettier": "5.0.0",
"eslint-plugin-promise": "6.1.1", "eslint-plugin-promise": "6.1.1",
"eslint-plugin-unicorn": "46.0.0", "eslint-plugin-unicorn": "48.0.0",
"html-w3c-validator": "1.2.2", "html-w3c-validator": "1.4.0",
"husky": "8.0.3", "husky": "8.0.3",
"lint-staged": "13.2.0", "lint-staged": "13.2.3",
"markdownlint-cli2": "0.6.0", "markdownlint-cli2": "0.8.1",
"markdownlint-rule-relative-links": "1.1.2", "markdownlint-rule-relative-links": "2.1.0",
"mockttp": "3.7.0", "mockttp": "3.9.1",
"next-translate-plugin": "2.0.4", "next-translate-plugin": "2.4.4",
"plop": "3.1.2", "plop": "3.1.2",
"postcss": "8.4.21", "postcss": "8.4.27",
"prettier": "2.8.7", "prettier": "3.0.0",
"prettier-plugin-tailwindcss": "0.2.6", "prettier-plugin-tailwindcss": "0.4.1",
"semantic-release": "21.0.1", "semantic-release": "21.0.7",
"start-server-and-test": "2.0.0", "start-server-and-test": "2.0.0",
"tailwindcss": "3.3.1", "tailwindcss": "3.3.3",
"typescript": "5.0.3", "typescript": "5.1.6"
"vercel": "28.18.3"
} }
} }

View File

@ -64,7 +64,7 @@ export const getServerSideProps = authenticationFromServerSide({
fetchData: async (context, api) => { fetchData: async (context, api) => {
const channelId = Number(context?.params?.['channelId']) const channelId = Number(context?.params?.['channelId'])
const guildId = Number(context?.params?.['guildId']) const guildId = Number(context?.params?.['guildId'])
if (isNaN(channelId) || isNaN(guildId)) { if (Number.isNaN(channelId) || Number.isNaN(guildId)) {
return { return {
notFound: true notFound: true
} }

View File

@ -59,7 +59,7 @@ export const getServerSideProps = authenticationFromServerSide({
fetchData: async (context, api) => { fetchData: async (context, api) => {
const channelId = Number(context?.params?.['channelId']) const channelId = Number(context?.params?.['channelId'])
const guildId = Number(context?.params?.['guildId']) const guildId = Number(context?.params?.['guildId'])
if (isNaN(channelId) || isNaN(guildId)) { if (Number.isNaN(channelId) || Number.isNaN(guildId)) {
return { return {
notFound: true notFound: true
} }

View File

@ -45,7 +45,7 @@ export const getServerSideProps = authenticationFromServerSide({
shouldBeAuthenticated: true, shouldBeAuthenticated: true,
fetchData: async (context, api) => { fetchData: async (context, api) => {
const guildId = Number(context?.params?.['guildId']) const guildId = Number(context?.params?.['guildId'])
if (isNaN(guildId)) { if (Number.isNaN(guildId)) {
return { return {
notFound: true notFound: true
} }

View File

@ -42,7 +42,7 @@ export const getServerSideProps = authenticationFromServerSide({
shouldBeAuthenticated: true, shouldBeAuthenticated: true,
fetchData: async (context, api) => { fetchData: async (context, api) => {
const guildId = Number(context?.params?.['guildId']) const guildId = Number(context?.params?.['guildId'])
if (isNaN(guildId)) { if (Number.isNaN(guildId)) {
return { return {
notFound: true notFound: true
} }

View File

@ -36,7 +36,7 @@ export const getServerSideProps = authenticationFromServerSide({
shouldBeAuthenticated: true, shouldBeAuthenticated: true,
fetchData: async (context, api) => { fetchData: async (context, api) => {
const userId = Number(context?.params?.['userId']) const userId = Number(context?.params?.['userId'])
if (isNaN(userId)) { if (Number.isNaN(userId)) {
return { return {
notFound: true notFound: true
} }

View File

Before

Width:  |  Height:  |  Size: 397 KiB

After

Width:  |  Height:  |  Size: 397 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -1,51 +0,0 @@
{
"name": "Thream",
"short_name": "Thream",
"theme_color": "#27B05E",
"background_color": "#262B3F",
"start_url": "/",
"display": "standalone",
"icons": [
{
"src": "images/icons/72x72.png",
"sizes": "72x72",
"type": "image/png"
},
{
"src": "images/icons/96x96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "images/icons/128x128.png",
"sizes": "128x128",
"type": "image/png"
},
{
"src": "images/icons/144x144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "images/icons/152x152.png",
"sizes": "152x152",
"type": "image/png"
},
{
"src": "images/icons/192x192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "images/icons/384x384.png",
"sizes": "384x384",
"type": "image/png"
},
{
"src": "images/icons/512x512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}

View File

@ -1,6 +1,6 @@
import axios from 'axios' import axios from 'axios'
export const API_VERSION = '1.2.5' export const API_VERSION = '1.2.8'
export const API_DEFAULT_PORT = 8080 export const API_DEFAULT_PORT = 8080

View File

@ -1,6 +0,0 @@
{
"$schema": "https://openapi.vercel.sh/vercel.json",
"github": {
"enabled": false
}
}