Погнали
Some checks failed
Deploy / server (push) Failing after 9s

closes #1
This commit is contained in:
Никита Круглицкий 2025-10-01 18:40:12 +06:00
commit 1d2b14d4c1
46 changed files with 15629 additions and 0 deletions

View File

@ -0,0 +1,40 @@
name: Deploy
on:
push:
branches:
- master
jobs:
server:
runs-on: ubuntu-latest
steps:
- name: Keyscan
run: |
ssh-keyscan git.koptilnya.xyz >> ~/.ssh/known_hosts
- name: Checkout
uses: actions/checkout@v4
with:
ssh-key: ${{ secrets.SSH_PRIVATE_KEY }}
ssh-strict: false
persist-credentials: false
- name: Build
run: docker build -f server/Dockerfile -t chad-server .
- name: Stop old container
run: docker rm -f chad-server || true
- name: Run
run: |
docker run -d \
--name chad-server \
--network traefik \
--label "traefik.enable=true" \
--label "traefik.http.routers.chad-server.rule=Host(`api.koptilnya.xyz`) && PathPrefix(`/chad`)"
--label "traefik.http.routers.chad-server.entrypoints=websecure" \
--label "traefik.http.routers.chad-server.tls.certresolver=myresolver" \
--label "traefik.http.services.chad-server.loadbalancer.server.port=80" \
chad-server:latest

8
.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

12
.idea/chad.iml generated Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
.idea/git_toolbox_blame.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GitToolBoxBlameSettings">
<option name="version" value="2" />
</component>
</project>

15
.idea/git_toolbox_prj.xml generated Normal file
View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GitToolBoxProjectSettings">
<option name="commitMessageIssueKeyValidationOverride">
<BoolValueOverride>
<option name="enabled" value="true" />
</BoolValueOverride>
</option>
<option name="commitMessageValidationEnabledOverride">
<BoolValueOverride>
<option name="enabled" value="true" />
</BoolValueOverride>
</option>
</component>
</project>

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>

6
.idea/jsLinters/eslint.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EslintConfiguration">
<option name="fix-on-save" value="true" />
</component>
</project>

8
.idea/modules.xml generated Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/chad.iml" filepath="$PROJECT_DIR$/.idea/chad.iml" />
</modules>
</component>
</project>

7
.idea/vcs.xml generated Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="$PROJECT_DIR$/server" vcs="Git" />
</component>
</project>

24
client/.gitignore vendored Normal file
View File

@ -0,0 +1,24 @@
# Nuxt dev/build outputs
.output
.data
.nuxt
.nitro
.cache
dist
# Node dependencies
node_modules
# Logs
logs
*.log
# Misc
.DS_Store
.fleet
.idea
# Local env files
.env
.env.*
!.env.example

Binary file not shown.

1
client/.yarnrc.yml Normal file
View File

@ -0,0 +1 @@
nodeLinker: node-modules

75
client/README.md Normal file
View File

@ -0,0 +1,75 @@
# Nuxt Minimal Starter
Look at the [Nuxt documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.
## Setup
Make sure to install dependencies:
```bash
# npm
npm install
# pnpm
pnpm install
# yarn
yarn install
# bun
bun install
```
## Development Server
Start the development server on `http://localhost:3000`:
```bash
# npm
npm run dev
# pnpm
pnpm dev
# yarn
yarn dev
# bun
bun run dev
```
## Production
Build the application for production:
```bash
# npm
npm run build
# pnpm
pnpm build
# yarn
yarn build
# bun
bun run build
```
Locally preview production build:
```bash
# npm
npm run preview
# pnpm
pnpm preview
# yarn
yarn preview
# bun
bun run preview
```
Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.

13
client/app/app.vue Normal file
View File

@ -0,0 +1,13 @@
<template>
<h1>yo</h1>
<pre>{{ connected }}</pre>
<audio v-for="(s, i) in streams" :key="i" :ref="(el) => onAudioRef(el, s)" autoplay controls />
</template>
<script lang="ts" setup>
const { connected, streams } = useMediasoup()
function onAudioRef(ref: Element, stream: MediaStream) {
(ref as HTMLAudioElement).srcObject = stream
}
</script>

View File

@ -0,0 +1,122 @@
import type { Socket } from 'socket.io-client'
import { createGlobalState } from '@vueuse/core'
import * as mediasoupClient from 'mediasoup-client'
import { io } from 'socket.io-client'
export const useMediasoup = createGlobalState(() => {
const socket: Socket = io('http://localhost:1337', {
transports: ['websocket'],
})
const initializing = ref(false)
const connected = ref(false)
const streams = shallowRef<MediaStream[]>([])
let device: mediasoupClient.Device
let sendTransport: mediasoupClient.types.Transport
let recvTransport: mediasoupClient.types.Transport
socket.on('newProducer', async ({ producerId }) => {
const params = await socket.emitWithAck('consume', {
producerId,
transportId: recvTransport.id,
rtpCapabilities: device.rtpCapabilities,
})
if (params?.error) {
console.error('consume error:', params.error)
return
}
const consumer = await recvTransport.consume(params)
const stream = new MediaStream([consumer.track])
streams.value.push(stream)
triggerRef(streams)
})
async function loadDevice() {
device = new mediasoupClient.Device()
const rtpCapabilities = await socket.emitWithAck('getRtpCapabilities')
await device.load({ routerRtpCapabilities: rtpCapabilities })
}
async function createSendTransport() {
const params = await socket.emitWithAck('createTransport')
sendTransport = device.createSendTransport(params)
sendTransport.on('connect', async ({ dtlsParameters }, callback, errback) => {
try {
await socket.emitWithAck('connectTransport', {
transportId: sendTransport.id,
dtlsParameters,
})
callback()
}
catch (err) {
errback(err)
}
})
sendTransport.on('produce', async ({ kind, rtpParameters }, callback, errback) => {
try {
const { id } = await socket.emitWithAck('produce', {
transportId: sendTransport.id,
kind,
rtpParameters,
})
callback({ id })
}
catch (err) {
errback(err)
}
})
}
async function publishMic() {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
const track = stream.getAudioTracks()[0]
await sendTransport.produce({ track })
}
async function createRecvTransport() {
const params = await socket.emitWithAck('createTransport')
recvTransport = device.createRecvTransport(params)
recvTransport.on('connect', async ({ dtlsParameters }, callback, errback) => {
try {
await socket.emitWithAck('connectTransport', {
transportId: recvTransport.id,
dtlsParameters,
})
callback()
}
catch (err) {
errback(err)
}
})
}
(async () => {
if (initializing.value || connected.value)
return
initializing.value = true
connected.value = false
await loadDevice()
await createSendTransport()
await createRecvTransport()
await publishMic()
initializing.value = false
connected.value = true
})()
return {
connected,
streams,
}
})

14
client/eslint.config.mjs Normal file
View File

@ -0,0 +1,14 @@
import antfu from '@antfu/eslint-config'
export default antfu({
formatters: {
css: true,
},
overrides: {
vue: {
'vue/block-order': ['error', {
order: ['template', 'script', 'style'],
}],
},
},
})

16
client/nuxt.config.ts Normal file
View File

@ -0,0 +1,16 @@
export default defineNuxtConfig({
compatibilityDate: '2025-09-29',
devtools: { enabled: true },
ssr: false,
devServer: {
// host: '0',
},
vite: {
clearScreen: false,
envPrefix: ['VITE_', 'TAURI_'],
server: {
strictPort: true,
},
},
ignore: ['**/src-tauri/**'],
})

28
client/package.json Normal file
View File

@ -0,0 +1,28 @@
{
"name": "nuxt-app",
"type": "module",
"private": true,
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare"
},
"dependencies": {
"@vueuse/core": "^13.9.0",
"mediasoup-client": "^3.16.7",
"nuxt": "^4.1.2",
"socket.io-client": "^4.8.1",
"typescript": "^5.9.3",
"vue": "^3.5.22",
"vue-router": "^4.5.1"
},
"packageManager": "yarn@4.10.3",
"devDependencies": {
"@antfu/eslint-config": "^5.4.1",
"@tauri-apps/cli": "^2.8.4",
"eslint": "^9.36.0",
"eslint-plugin-format": "^1.0.2"
}
}

BIN
client/public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

2
client/public/robots.txt Normal file
View File

@ -0,0 +1,2 @@
User-Agent: *
Disallow:

4
client/src-tauri/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
# Generated by Cargo
# will have compiled files and executables
/target/
/gen/schemas

5068
client/src-tauri/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,25 @@
[package]
name = "app"
version = "0.1.0"
description = "A Tauri App"
authors = ["you"]
license = ""
repository = ""
edition = "2021"
rust-version = "1.77.2"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
name = "app_lib"
crate-type = ["staticlib", "cdylib", "rlib"]
[build-dependencies]
tauri-build = { version = "2.4.1", features = [] }
[dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
log = "0.4"
tauri = { version = "2.8.5", features = [] }
tauri-plugin-log = "2"

View File

@ -0,0 +1,3 @@
fn main() {
tauri_build::build()
}

View File

@ -0,0 +1,11 @@
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "enables the default permissions",
"windows": [
"main"
],
"permissions": [
"core:default"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@ -0,0 +1,16 @@
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.setup(|app| {
if cfg!(debug_assertions) {
app.handle().plugin(
tauri_plugin_log::Builder::default()
.level(log::LevelFilter::Info)
.build(),
)?;
}
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}

View File

@ -0,0 +1,6 @@
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
fn main() {
app_lib::run();
}

View File

@ -0,0 +1,37 @@
{
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"productName": "chad",
"version": "0.1.0",
"identifier": "com.tauri.dev",
"build": {
"frontendDist": "../dist",
"devUrl": "http://localhost:3000",
"beforeDevCommand": "yarn dev",
"beforeBuildCommand": "yarn build"
},
"app": {
"windows": [
{
"title": "Chad",
"width": 800,
"height": 600,
"resizable": false,
"fullscreen": false
}
],
"security": {
"csp": null
}
},
"bundle": {
"active": true,
"targets": "all",
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
]
}
}

18
client/tsconfig.json Normal file
View File

@ -0,0 +1,18 @@
{
// https://nuxt.com/docs/guide/concepts/typescript
"files": [],
"references": [
{
"path": "./.nuxt/tsconfig.app.json"
},
{
"path": "./.nuxt/tsconfig.server.json"
},
{
"path": "./.nuxt/tsconfig.shared.json"
},
{
"path": "./.nuxt/tsconfig.node.json"
}
]
}

10038
client/yarn.lock Normal file

File diff suppressed because it is too large Load Diff