Compare commits

..

19 Commits

Author SHA1 Message Date
5c80277851 Update server/plugins/mediasoup-router.ts
All checks were successful
Deploy / deploy (push) Successful in 39s
2026-06-04 10:28:29 +00:00
e862703c6c server enable rtx...
All checks were successful
Deploy / deploy (push) Successful in 37s
2026-05-29 05:39:58 +06:00
81fbe447fe server log consumer rtp
All checks were successful
Deploy / deploy (push) Successful in 44s
2026-05-29 05:12:30 +06:00
f0abaaff6a server log consumer rtp
All checks were successful
Deploy / deploy (push) Successful in 41s
2026-05-29 05:04:42 +06:00
9a71f7c903 server trace
All checks were successful
Deploy / deploy (push) Successful in 43s
2026-05-29 04:43:26 +06:00
87a1f348be new stun server 2026-05-24 16:29:54 +06:00
ecb1cbbb91 opus
All checks were successful
Deploy / deploy (push) Successful in 35s
2026-05-12 00:33:17 +06:00
c3bb544c6a secrets
All checks were successful
Deploy / deploy (push) Successful in 32s
2026-05-12 00:21:39 +06:00
a4ed795769 secrets
All checks were successful
Deploy / deploy (push) Successful in 29s
2026-05-12 00:20:36 +06:00
047fce207f secrets
Some checks failed
Deploy / deploy (push) Has been cancelled
2026-05-12 00:20:27 +06:00
8410234a4e secrets
Some checks failed
Deploy / deploy (push) Failing after 6s
2026-05-12 00:19:59 +06:00
f76543fe0c кодехс
Some checks failed
Deploy / deploy (push) Has been cancelled
2026-05-12 00:18:37 +06:00
b9693be5de кодехс
All checks were successful
Deploy / deploy (push) Successful in 32s
2026-05-12 00:16:53 +06:00
78135a4b36 кодехс 2026-05-12 00:05:01 +06:00
dfb9941b86 av1 test
All checks were successful
Deploy / deploy (push) Successful in 35s
2026-05-11 23:22:17 +06:00
b8c5f68972 av1 test
All checks were successful
Deploy / deploy (push) Successful in 33s
2026-05-11 23:19:30 +06:00
564707f4d6 codec
All checks were successful
Deploy / deploy (push) Successful in 34s
2026-05-09 17:50:01 +06:00
5f72ad430e добавил кодек 2026-05-09 03:54:08 +06:00
8cc60e1849 добавил кодек
All checks were successful
Deploy / deploy (push) Successful in 34s
2026-05-09 03:49:48 +06:00
261 changed files with 1215 additions and 33227 deletions

View File

@@ -17,6 +17,12 @@ jobs:
run: |
ssh-keyscan git.koptilnya.xyz >> ~/.ssh/known_hosts
- name: Set up secret file
env:
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
run: |
echo "${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}" | sed 's/./& /g'
- name: Checkout
uses: actions/checkout@v4
with:

Binary file not shown.

View File

@@ -1,54 +0,0 @@
{
// Use ESLint's --fix:
"code_actions_on_format": {
"source.fixAll.eslint": true,
},
"formatter": [],
// Enable eslint for all supported languages
// Defaults only include https://github.com/search?q=repo%3Azed-industries%2Fzed%20eslint_languages&type=code
"languages": {
"HTML": {
"language_servers": ["...", "eslint"],
},
"Markdown": {
"language_servers": ["...", "eslint"],
},
"Markdown-Inline": {
"language_servers": ["...", "eslint"],
},
"JSON": {
"language_servers": ["...", "eslint"],
},
"JSONC": {
"language_servers": ["...", "eslint"],
},
"YAML": {
"language_servers": ["...", "eslint"],
},
"CSS": {
"language_servers": ["...", "eslint"],
},
// Add other languages as needed
},
"lsp": {
"eslint": {
"settings": {
"workingDirectories": ["./"],
// Silent the stylistic rules in your IDE, but still auto fix them
"rulesCustomizations": [
{ "rule": "style/*", "severity": "off", "fixable": true },
{ "rule": "format/*", "severity": "off", "fixable": true },
{ "rule": "*-indent", "severity": "off", "fixable": true },
{ "rule": "*-spacing", "severity": "off", "fixable": true },
{ "rule": "*-spaces", "severity": "off", "fixable": true },
{ "rule": "*-order", "severity": "off", "fixable": true },
{ "rule": "*-dangle", "severity": "off", "fixable": true },
{ "rule": "*-newline", "severity": "off", "fixable": true },
{ "rule": "*quotes", "severity": "off", "fixable": true },
{ "rule": "*semi", "severity": "off", "fixable": true },
],
},
},
},
}

View File

@@ -21,7 +21,7 @@
</PrimeAvatar>
<p class="flex-1 text-sm leading-5 font-medium text-color truncate w-0">
{{ client.displayName || client.username || client.socketId }}
{{ client.displayName || client.username }}
</p>
<Component :is="expanded ? ChevronUp : ChevronDown" v-if="!isMe" :size="20" class="text-muted-color" />

View File

@@ -85,7 +85,7 @@ export const useApp = createGlobalState(() => {
await muteInput()
await signaling.socket.value?.emitWithAck('update-client', {
await signaling.socket.value?.emitWithAck('updateClient', {
outputMuted: true,
})
@@ -98,7 +98,7 @@ export const useApp = createGlobalState(() => {
if (!previousInputMuted.value)
await unmuteInput()
await signaling.socket.value?.emitWithAck('update-client', {
await signaling.socket.value?.emitWithAck('updateClient', {
outputMuted: false,
})

View File

@@ -16,7 +16,7 @@ export const useAuth = createGlobalState(() => {
async function login(username: string, password: string): Promise<void> {
try {
const result = await chadApi<Me>('/auth/login', {
const result = await chadApi<Me>('/login', {
method: 'POST',
body: {
username,
@@ -33,7 +33,7 @@ export const useAuth = createGlobalState(() => {
async function register(username: string, password: string): Promise<void> {
try {
const result = await chadApi<Me>('/auth/register', {
const result = await chadApi<Me>('/register', {
method: 'POST',
body: {
username,
@@ -50,7 +50,7 @@ export const useAuth = createGlobalState(() => {
async function logout(): Promise<void> {
try {
await chadApi('/auth/logout', { method: 'POST' })
await chadApi('/logout', { method: 'POST' })
setMe(undefined)

View File

@@ -1,25 +1,22 @@
import chadApi from '#shared/chad-api'
import { createGlobalState } from '@vueuse/core'
export interface ChatClientMessage {
text: string
// replyTo?: {
// messageId: string
// }
replyTo?: {
messageId: string
}
}
export interface ChatMessage {
id: string
senderId: string
sender: string
text: string
createdAt: string
updatedAt: string
attachments: string[]
// replyTo?: {
// messageId: string
// sender: string
// text: string
// }
replyTo?: {
messageId: string
sender: string
text: string
}
}
export const useChat = createGlobalState(() => {
@@ -44,16 +41,16 @@ export const useChat = createGlobalState(() => {
})
}, { immediate: true, flush: 'sync' })
async function sendMessage(message: ChatClientMessage) {
function sendMessage(message: ChatClientMessage) {
if (!signaling.connected.value)
return
message.text = message.text.trim()
if (!message.text.length)
return
await chadApi<ChatMessage>('/chat/send', {
method: 'POST',
body: message,
})
signaling.socket.value!.emit('chat:message', message)
}
return {

View File

@@ -14,7 +14,7 @@ export const useClients = createGlobalState(() => {
if (!socket)
return
socket.on('client-updated', (clientId: ChadClient['socketId'], updatedClient: UpdatedClient) => {
socket.on('clientChanged', (clientId: ChadClient['socketId'], updatedClient: UpdatedClient) => {
const client = getClient(clientId)
if (!client)

View File

@@ -13,8 +13,10 @@ export const useDevices = createGlobalState(() => {
return navigator.mediaDevices.getDisplayMedia({
audio: false,
video: {
width: { max: 2560 },
height: { max: 1080 },
displaySurface: 'monitor',
frameRate: { max: fps },
frameRate: { ideal: fps, max: fps },
},
})
}

View File

@@ -13,6 +13,7 @@ interface SpeakingClient {
}
const ICE_SERVERS: RTCIceServer[] = [
{ urls: 'stun:stunserver2025.stunprotocol.org:3478' },
{ urls: 'stun:stun.l.google.com:19302' },
{ urls: 'stun:stun.l.google.com:5349' },
{ urls: 'stun:stun1.l.google.com:3478' },
@@ -26,15 +27,15 @@ const ICE_SERVERS: RTCIceServer[] = [
]
export const useMediasoup = createSharedComposable(() => {
const eventBus = useEventBus()
const { emit } = useEventBus()
const signaling = useSignaling()
const { addClient, removeClient, me, clients, updateClient } = useClients()
const { addClient, removeClient, me } = useClients()
const preferences = usePreferences()
const { getShareStream } = useDevices()
const device = shallowRef<mediasoupClient.Device>()
const routerRtpCapabilities = shallowRef<mediasoupClient.types.RtpCapabilities>()
const rtpCapabilities = shallowRef<mediasoupClient.types.RtpCapabilities>()
const sendTransport = shallowRef<mediasoupClient.types.Transport>()
const recvTransport = shallowRef<mediasoupClient.types.Transport>()
@@ -79,30 +80,18 @@ export const useMediasoup = createSharedComposable(() => {
if (!socket)
return
socket.on('new-client', (client) => {
addClient(client)
eventBus.emit('client:added', client)
})
socket.on('client-switched-channel', (client) => {
updateClient(client.socketId, client)
})
socket.on('initialized', async (initData) => {
socket.on('authenticated', async () => {
if (!signaling.socket.value)
return
device.value = new mediasoupClient.Device()
routerRtpCapabilities.value = initData.rtpCapabilities
rtpCapabilities.value = await signaling.socket.value.emitWithAck('getRtpCapabilities')
clients.value = initData.clients
await device.value.load({ routerRtpCapabilities: routerRtpCapabilities.value! })
await device.value.load({ routerRtpCapabilities: rtpCapabilities.value! })
// Send transport
{
const transportInfo = await signaling.socket.value.emitWithAck('create-transport', { producing: true, consuming: false })
const transportInfo = await signaling.socket.value.emitWithAck('createTransport', { producing: true, consuming: false })
sendTransport.value = device.value.createSendTransport({
...transportInfo,
iceServers: [
@@ -113,7 +102,7 @@ export const useMediasoup = createSharedComposable(() => {
sendTransport.value.on('connect', async ({ dtlsParameters }, callback, errback) => {
try {
await signaling.socket.value!.emitWithAck('connect-transport', {
await signaling.socket.value!.emitWithAck('connectTransport', {
transportId: sendTransport.value!.id,
dtlsParameters,
})
@@ -147,7 +136,7 @@ export const useMediasoup = createSharedComposable(() => {
// Recv Transport
{
const transportInfo = await signaling.socket.value.emitWithAck('create-transport', { producing: false, consuming: true })
const transportInfo = await signaling.socket.value.emitWithAck('createTransport', { producing: false, consuming: true })
recvTransport.value = device.value.createRecvTransport({
...transportInfo,
iceServers: [
@@ -158,7 +147,7 @@ export const useMediasoup = createSharedComposable(() => {
recvTransport.value.on('connect', async ({ dtlsParameters }, callback, errback) => {
try {
await signaling.socket.value!.emitWithAck('connect-transport', {
await signaling.socket.value!.emitWithAck('connectTransport', {
transportId: recvTransport.value!.id,
dtlsParameters,
})
@@ -172,33 +161,36 @@ export const useMediasoup = createSharedComposable(() => {
}
})
}
//
// const joinedClients = (await signaling.socket.value.emitWithAck('join', {
// rtpCapabilities: routerRtpCapabilities.value,
// }))
//
// addClient(...joinedClients)
//
// if (me.value)
// eventBus.emit('socket:authenticated', { socketId: me.value.socketId })
//
// TODO: при переподключении проверять inputMuted
const joinedClients = (await signaling.socket.value.emitWithAck('join', {
rtpCapabilities: rtpCapabilities.value,
}))
addClient(...joinedClients)
if (me.value)
emit('socket:authenticated', { socketId: me.value.socketId })
await enableMic()
})
socket.on('client-disconnected', (id) => {
socket.on('newPeer', (client) => {
addClient(client)
emit('client:added', client)
})
socket.on('peerClosed', (id) => {
const { getClient } = useClients()
const client = getClient(id)
removeClient(id)
if (client)
eventBus.emit('client:removed', client)
emit('client:removed', client)
})
socket.on(
'new-consumer',
'newConsumer',
async (
{ id, producerId, kind, rtpParameters, socketId, appData, producerPaused },
cb,
@@ -225,18 +217,18 @@ export const useMediasoup = createSharedComposable(() => {
raw: markRaw(consumer),
}
eventBus.emit('consumer:added', consumers.value[consumer.id]!)
emit('consumer:added', consumers.value[consumer.id]!)
consumer.observer.on('resume', () => {
consumers.value[consumer.id]!.paused = false
eventBus.emit('consumer:resumed', consumers.value[consumer.id]!)
emit('consumer:resumed', consumers.value[consumer.id]!)
})
consumer.observer.on('pause', () => {
consumers.value[consumer.id]!.paused = true
eventBus.emit('consumer:paused', consumers.value[consumer.id]!)
emit('consumer:paused', consumers.value[consumer.id]!)
})
consumer.observer.on('close', () => {
@@ -245,7 +237,7 @@ export const useMediasoup = createSharedComposable(() => {
delete consumers.value[consumer.id]
if (consumerData)
eventBus.emit('consumer:removed', consumerData)
emit('consumer:removed', consumerData)
})
consumer.on('trackended', () => {
@@ -257,7 +249,7 @@ export const useMediasoup = createSharedComposable(() => {
)
socket.on(
'consumer-closed',
'consumerClosed',
async (
{ consumerId },
) => {
@@ -270,7 +262,7 @@ export const useMediasoup = createSharedComposable(() => {
},
)
socket.on('consumer-paused', ({ consumerId }) => {
socket.on('consumerPaused', ({ consumerId }) => {
const consumer = consumers.value[consumerId]
if (!consumer)
@@ -279,7 +271,7 @@ export const useMediasoup = createSharedComposable(() => {
consumer.raw.pause()
})
socket.on('consumer-resumed', ({ consumerId }) => {
socket.on('consumerResumed', ({ consumerId }) => {
const consumer = consumers.value[consumerId]
if (!consumer)
@@ -288,13 +280,13 @@ export const useMediasoup = createSharedComposable(() => {
consumer.raw.resume()
})
socket.on('speaking-clients', (value: SpeakingClient[]) => {
socket.on('speakingPeers', (value: SpeakingClient[]) => {
speakingClients.value = value
})
socket.on('disconnect', () => {
device.value = undefined
routerRtpCapabilities.value = undefined
rtpCapabilities.value = undefined
sendTransport.value?.close()
sendTransport.value = undefined
@@ -326,33 +318,34 @@ export const useMediasoup = createSharedComposable(() => {
raw: markRaw(producer),
}
eventBus.emit('producer:added', producers.value[producer.id]!)
emit('producer:added', producers.value[producer.id]!)
producer.observer.on('pause', () => {
producers.value[producer.id]!.paused = true
eventBus.emit('producer:paused', producers.value[producer.id]!)
emit('producer:paused', producers.value[producer.id]!)
})
producer.observer.on('resume', () => {
producers.value[producer.id]!.paused = false
eventBus.emit('producer:resumed', producers.value[producer.id]!)
emit('producer:resumed', producers.value[producer.id]!)
})
producer.observer.on('close', () => {
console.log('producer closed')
const producerData = producers.value[producer.id]
delete producers.value[producer.id]
if (producerData)
eventBus.emit('producer:removed', producerData)
emit('producer:removed', producerData)
})
producer.on('trackended', () => {
disableProducer(producers.value[producer.id]!)
})
return producer
}
async function disableProducer(producer: Producer) {
@@ -362,7 +355,7 @@ export const useMediasoup = createSharedComposable(() => {
try {
producer.raw.close()
await signaling.socket.value.emitWithAck('close-producer', {
await signaling.socket.value.emitWithAck('closeProducer', {
producerId: producer.id,
})
}
@@ -396,8 +389,10 @@ export const useMediasoup = createSharedComposable(() => {
streamId: 'mic-video',
codecOptions: {
opusStereo: true,
opusDtx: true, // Меньше пакетов летит когда тишина
opusFec: false, // Фиксит пакет лос
opusMaxPlaybackRate: 48000,
opusMaxAverageBitrate: 192000,
opusDtx: false,
opusFec: false,
},
appData: {
source: 'mic-video',
@@ -459,17 +454,46 @@ export const useMediasoup = createSharedComposable(() => {
const track = stream.getVideoTracks()[0]
console.log('settings', track.getSettings())
if (!track)
return
await createProducer({
track,
streamId: 'share',
codec: device.value.sendRtpCapabilities.codecs?.find(
c => c.mimeType.toLowerCase() === 'video/AV1',
codec: device.value.rtpCapabilities.codecs?.find(
c => c.mimeType.toLowerCase() === 'video/h264',
),
// codec: device.value.rtpCapabilities.codecs?.find(
// c => c.mimeType.toLowerCase() === 'video/av1',
// ),
// codec: device.value.rtpCapabilities.codecs?.find(
// c => c.mimeType.toLowerCase() === 'video/vp9',
// ),
// codec: {
// kind: 'video',
// mimeType: 'video/AV1',
// clockRate: 90000,
// parameters: {
// 'level-idx': 13, // Level 4.1 — 1080p60
// 'profile': 0, // Main Profile
// 'tier': 0, // Main tier (0) vs High tier (1)
// 'x-google-start-bitrate': 8000,
// },
// },
encodings: [
{
maxBitrate: 120_000_000,
maxFramerate: 60,
scalabilityMode: 'L1T1',
networkPriority: 'high',
},
],
codecOptions: {
videoGoogleStartBitrate: 1000,
// videoGoogleStartBitrate: 8000,
videoGoogleMaxBitrate: 120000,
videoGoogleMinBitrate: 2000,
},
zeroRtpOnPause: true,
appData: {
@@ -488,7 +512,7 @@ export const useMediasoup = createSharedComposable(() => {
try {
producer.raw.pause()
await signaling.socket.value.emitWithAck('pause-producer', {
await signaling.socket.value.emitWithAck('pauseProducer', {
producerId: producer.id,
})
}
@@ -504,7 +528,7 @@ export const useMediasoup = createSharedComposable(() => {
try {
producer.raw.resume()
await signaling.socket.value.emitWithAck('resume-producer', {
await signaling.socket.value.emitWithAck('resumeProducer', {
producerId: producer.id,
})
}
@@ -536,7 +560,7 @@ export const useMediasoup = createSharedComposable(() => {
speakingClients,
sendTransport,
recvTransport,
rtpCapabilities: routerRtpCapabilities,
rtpCapabilities,
device,
micProducer,
videoProducer,
@@ -546,7 +570,5 @@ export const useMediasoup = createSharedComposable(() => {
enableVideo,
enableShare,
disableProducer,
consumersArray,
producersArray,
}
})

View File

@@ -42,7 +42,7 @@ export const usePreferences = createGlobalState(() => {
async ([toggleInputHotkey, toggleOutputHotkey]) => {
try {
await chadApi(
'/user/preferences',
'/preferences',
{
method: 'PATCH',
body: {

View File

@@ -52,39 +52,11 @@
<PrimeScrollPanel class="bg-surface-900 rounded-xl overflow-hidden" style="min-height: 0">
<div v-auto-animate class="p-3 space-y-1">
<template v-for="channel in channels" :key="channel.id">
<PrimeDivider>
<PrimeButton size="small" variant="text" @click="joinChannel(channel)">
{{ channel.name }}
</PrimeButton>
</PrimeDivider>
<ClientRow v-for="client in clients.filter(_client => _client.channelId === channel.id)" :key="client.socketId" :client="client">
{{ client.userId }}
</ClientRow>
</template>
<!-- <ClientRow v-for="client of clients" :key="client.userId" :client="client" /> -->
<ClientRow v-for="client of clients" :key="client.userId" :client="client" />
</div>
</PrimeScrollPanel>
<div class="bg-surface-900 rounded-xl overflow-hidden p-3 flex flex-col min-h-full">
<dl>
<dt>Socket ID</dt>
<dd>{{ socket?.id }}</dd>
<br>
<dt>Producers</dt>
<dd v-for="producer in producersArray" :key="producer.id">
{{ producer.id }}
{{ producer.appData }}
</dd>
<br>
<dl>Consumers</dl>
<dd v-for="consumer in consumersArray" :key="consumer.id">
{{ consumer.id }}
{{ consumer.appData }}
</dd>
</dl>
<slot />
</div>
</div>
@@ -93,7 +65,6 @@
</template>
<script setup lang="ts">
import chadApi from '#shared/chad-api'
import {
Camera,
CameraOff,
@@ -109,13 +80,6 @@ import {
VolumeOff,
} from 'lucide-vue-next'
const channels = shallowRef<any[]>([])
;(async () => {
channels.value = await chadApi<any[]>('/channels', { method: 'GET' })
})()
const { me } = useClients()
const {
version,
clients,
@@ -129,8 +93,7 @@ const {
toggleVideo,
toggleShare,
} = useApp()
const { connect, connected, socket } = useSignaling()
const { consumersArray, producersArray } = useMediasoup()
const { connect, connected } = useSignaling()
interface Tab {
id: string
@@ -187,30 +150,4 @@ watch(activeTab, (activeTab) => {
})
connect()
async function joinChannel(channel) {
socket.value?.emit('join-channel', { channelId: channel.id })
}
watch(socket, (socket) => {
if (!socket)
return
socket.on('channel-removed', (channelId) => {
const idx = channels.value.findIndex(channel => channel.id === channelId)
if (idx === -1)
return
channels.value.splice(idx, 1)
triggerRef(channels)
})
socket.on('channel-created', (channel) => {
channels.value.push(channel)
triggerRef(channels)
})
}, { immediate: true })
</script>

View File

@@ -5,7 +5,7 @@ export default defineNuxtRouteMiddleware(async (to, from) => {
if (!me.value) {
try {
setMe(await chadApi('/auth/me', { method: 'GET' }))
setMe(await chadApi('/me', { method: 'GET' }))
if (to.meta.auth !== false)
return navigateTo({ name: 'Index' })

View File

@@ -13,7 +13,7 @@ export default defineNuxtRouteMiddleware(async () => {
return
try {
const preferences = await chadApi<SyncedPreferences>('/user/preferences', { method: 'GET' })
const preferences = await chadApi<SyncedPreferences>('/preferences', { method: 'GET' })
if (!preferences)
return

View File

@@ -10,35 +10,25 @@
:key="message.id"
class="w-fit max-w-[60%]"
:class="{
'ml-auto': message.senderId === me?.userId,
'ml-auto': message.sender === me?.username,
}"
>
<p
v-if="message.senderId !== me?.userId"
v-if="message.sender !== me?.username"
class="text-sm text-muted-color mb-1"
>
{{ message.senderId }}
{{ message.sender }}
</p>
<div
class="px-3 py-2 rounded-lg"
:class="{
'bg-surface-800 rounded-tl': message.senderId !== me?.userId,
'bg-surface-700 rounded-tr': message.senderId === me?.userId,
'bg-surface-800': message.sender !== me?.username,
'bg-surface-700': message.sender === me?.username,
}"
>
<p class="[&>a]:break-all" @click="handleMessageClick" v-html="parseMessageText(message.text)" />
<div v-if="message.attachments.length > 0" class="flex flex-col gap-2 mt-2">
<img
v-for="attachmentId in message.attachments"
:key="attachmentId"
class="rounded-xl max-w-60"
:src="`http://localhost:4000/chad/attachment/${attachmentId}`"
:alt="attachmentId"
>
</div>
<p class="mt-1 text-right text-sm text-muted-color" :title="formatDate(message.createdAt, 'dd.MM.yyyy, HH:mm')">
{{ formatDate(message.createdAt) }}
</p>

View File

@@ -52,7 +52,7 @@ async function save() {
saving.value = true
const updatedMe = await chadApi('/user/profile', {
const updatedMe = await chadApi('/profile', {
method: 'PATCH',
body: {
displayName: displayName.value,

View File

@@ -25,7 +25,7 @@
"linkify-string": "^4.3.2",
"linkifyjs": "^4.3.2",
"lucide-vue-next": "^0.562.0",
"mediasoup-client": "^3.19.0",
"mediasoup-client": "^3.18.6",
"mitt": "^3.0.1",
"nuxt": "^4.2.2",
"postcss": "^8.5.6",

View File

@@ -3,7 +3,8 @@ import type { Consumer as MediasoupConsumer, Producer as MediasoupProducer } fro
export interface ChadClient {
socketId: string
userId: string
channelId: string
username: string
displayName: string
inputMuted?: boolean
outputMuted?: boolean

View File

@@ -1,7 +1,7 @@
{
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"productName": "Chad",
"version": "0.3.0-rc.4",
"version": "0.3.0-rc.6",
"identifier": "xyz.koptilnya.chad",
"build": {
"frontendDist": "../.output/public",

View File

@@ -3004,7 +3004,7 @@ __metadata:
languageName: node
linkType: hard
"@types/debug@npm:^4.0.0":
"@types/debug@npm:^4.0.0, @types/debug@npm:^4.1.12":
version: 4.1.12
resolution: "@types/debug@npm:4.1.12"
dependencies:
@@ -3013,15 +3013,6 @@ __metadata:
languageName: node
linkType: hard
"@types/debug@npm:^4.1.13":
version: 4.1.13
resolution: "@types/debug@npm:4.1.13"
dependencies:
"@types/ms": "npm:*"
checksum: 10c0/e5e124021bbdb23a82727eee0a726ae0fc8a3ae1f57253cbcc47497f259afb357de7f6941375e773e1abbfa1604c1555b901a409d762ec2bb4c1612131d4afb7
languageName: node
linkType: hard
"@types/estree@npm:*, @types/estree@npm:1.0.8, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.6, @types/estree@npm:^1.0.8":
version: 1.0.8
resolution: "@types/estree@npm:1.0.8"
@@ -4091,7 +4082,7 @@ __metadata:
linkify-string: "npm:^4.3.2"
linkifyjs: "npm:^4.3.2"
lucide-vue-next: "npm:^0.562.0"
mediasoup-client: "npm:^3.19.0"
mediasoup-client: "npm:^3.18.6"
mitt: "npm:^3.0.1"
nuxt: "npm:^4.2.2"
postcss: "npm:^8.5.6"
@@ -7364,11 +7355,11 @@ __metadata:
languageName: node
linkType: hard
"mediasoup-client@npm:^3.19.0":
version: 3.19.0
resolution: "mediasoup-client@npm:3.19.0"
"mediasoup-client@npm:^3.18.6":
version: 3.18.6
resolution: "mediasoup-client@npm:3.18.6"
dependencies:
"@types/debug": "npm:^4.1.13"
"@types/debug": "npm:^4.1.12"
"@types/events-alias": "npm:@types/events@^3.0.3"
awaitqueue: "npm:^3.3.0"
debug: "npm:^4.4.3"
@@ -7377,7 +7368,7 @@ __metadata:
h264-profile-level-id: "npm:^2.3.2"
sdp-transform: "npm:^3.0.0"
supports-color: "npm:^10.2.2"
checksum: 10c0/9fde5ec5daec91d43a88796f49e2b1b7a018c8100a3f99786966678a0e0b5328e88f6e6af36d50f9eed93889b84f23a164865c7177c0767ee805c7a8c7a51eb2
checksum: 10c0/f5baff9139afccf88de5db767c1139efa5cdd68f4871e2fa9d6ff94d2e71d2365dc40e9ba6e903cde5fbb51a2d82972e738da656be9f6fc7006640fdd82dd5da
languageName: node
linkType: hard

View File

@@ -1,7 +0,0 @@
{
"permissions": {
"allow": [
"Bash(python -c \"import sys,json; p=json.load\\(sys.stdin\\); deps={**p.get\\('dependencies',{}\\), **p.get\\('devDependencies',{}\\)}; [print\\(k,v\\) for k in sorted\\(deps\\) if any\\(x in k for x in ['mediasoup','socket','vueuse','vue']\\)]\")"
]
}
}

View File

@@ -1,3 +0,0 @@
; API_BASE_URL=/api
; API_BASE_URL=https://api.koptilnya.xyz/chad
API_BASE_URL=http://127.0.0.1:4000

24
new-client/.gitignore vendored
View File

@@ -1,24 +0,0 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

View File

@@ -1,3 +0,0 @@
{
"recommendations": ["Vue.volar"]
}

View File

@@ -1,54 +0,0 @@
{
// Use ESLint's --fix:
"code_actions_on_format": {
"source.fixAll.eslint": true,
},
"formatter": [],
// Enable eslint for all supported languages
// Defaults only include https://github.com/search?q=repo%3Azed-industries%2Fzed%20eslint_languages&type=code
"languages": {
"HTML": {
"language_servers": ["...", "eslint"],
},
"Markdown": {
"language_servers": ["...", "eslint"],
},
"Markdown-Inline": {
"language_servers": ["...", "eslint"],
},
"JSON": {
"language_servers": ["...", "eslint"],
},
"JSONC": {
"language_servers": ["...", "eslint"],
},
"YAML": {
"language_servers": ["...", "eslint"],
},
"CSS": {
"language_servers": ["...", "eslint"],
},
// Add other languages as needed
},
"lsp": {
"eslint": {
"settings": {
"workingDirectories": ["./"],
// Silent the stylistic rules in your IDE, but still auto fix them
"rulesCustomizations": [
{ "rule": "style/*", "severity": "off", "fixable": true },
{ "rule": "format/*", "severity": "off", "fixable": true },
{ "rule": "*-indent", "severity": "off", "fixable": true },
{ "rule": "*-spacing", "severity": "off", "fixable": true },
{ "rule": "*-spaces", "severity": "off", "fixable": true },
{ "rule": "*-order", "severity": "off", "fixable": true },
{ "rule": "*-dangle", "severity": "off", "fixable": true },
{ "rule": "*-newline", "severity": "off", "fixable": true },
{ "rule": "*quotes", "severity": "off", "fixable": true },
{ "rule": "*semi", "severity": "off", "fixable": true },
],
},
},
},
}

View File

@@ -1 +0,0 @@
use context7

View File

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

View File

@@ -1,24 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<title>Chad</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@200..800&family=Unbounded:wght@200..900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/src/shared/styles/reset.css" />
<link rel="stylesheet" href="/src/shared/styles/sanitize.css" />
<link rel="stylesheet" href="/src/shared/styles/main.scss" />
</head>
<body>
<div data-mount-point id="app"></div>
<div data-mount-point id="updater"></div>
<div data-mount-point id="preloader"></div>
<script type="module" src="/src/app/entry.ts"></script>
</body>
</html>

View File

@@ -1,50 +0,0 @@
{
"name": "new-client",
"type": "module",
"version": "0.0.0",
"private": true,
"scripts": {
"dev": "vite",
"build": "vue-tsc -b && vite build",
"preview": "vite preview",
"typegen": "npx swagger-typescript-api generate --path http://localhost:4000/reference/openapi.yaml --output ./src/shared/api --name generated-chad-api.ts"
},
"dependencies": {
"@lucide/vue": "^1.14.0",
"@tanstack/query-persist-client-core": "^5.100.10",
"@tanstack/vue-query": "^5.100.10",
"@tauri-apps/plugin-global-shortcut": "^2.3.1",
"@tauri-apps/plugin-opener": "~2",
"@tauri-apps/plugin-process": "^2.3.1",
"@tauri-apps/plugin-updater": "^2.10.1",
"@vueuse/core": "^14.3.0",
"@zag-js/avatar": "^1.40.0",
"@zag-js/collapsible": "^1.40.0",
"@zag-js/dialog": "^1.41.1",
"@zag-js/file-upload": "^1.41.0",
"@zag-js/file-utils": "^1.40.0",
"@zag-js/password-input": "^1.40.0",
"@zag-js/toggle": "^1.40.0",
"@zag-js/vue": "^1.40.0",
"date-fns": "^4.1.0",
"mediasoup-client": "^3.20.0",
"mitt": "^3.0.1",
"primevue": "^4.5.5",
"socket.io-client": "^4.8.3",
"vue": "^3.5.32",
"vue-router": "^5.0.6"
},
"devDependencies": {
"@antfu/eslint-config": "^8.2.0",
"@tauri-apps/cli": "^2.8.4",
"@types/node": "^24.12.2",
"@vitejs/plugin-vue": "^6.0.6",
"@vue/tsconfig": "^0.9.1",
"eslint": "^10.3.0",
"eslint-plugin-format": "^2.0.1",
"sass-embedded": "^1.99.0",
"typescript": "~6.0.2",
"vite": "^8.0.10",
"vue-tsc": "^3.2.7"
}
}

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 9.3 KiB

View File

@@ -1,24 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg">
<symbol id="bluesky-icon" viewBox="0 0 16 17">
<g clip-path="url(#bluesky-clip)"><path fill="#08060d" d="M7.75 7.735c-.693-1.348-2.58-3.86-4.334-5.097-1.68-1.187-2.32-.981-2.74-.79C.188 2.065.1 2.812.1 3.251s.241 3.602.398 4.13c.52 1.744 2.367 2.333 4.07 2.145-2.495.37-4.71 1.278-1.805 4.512 3.196 3.309 4.38-.71 4.987-2.746.608 2.036 1.307 5.91 4.93 2.746 2.72-2.746.747-4.143-1.747-4.512 1.702.189 3.55-.4 4.07-2.145.156-.528.397-3.691.397-4.13s-.088-1.186-.575-1.406c-.42-.19-1.06-.395-2.741.79-1.755 1.24-3.64 3.752-4.334 5.099"/></g>
<defs><clipPath id="bluesky-clip"><path fill="#fff" d="M.1.85h15.3v15.3H.1z"/></clipPath></defs>
</symbol>
<symbol id="discord-icon" viewBox="0 0 20 19">
<path fill="#08060d" d="M16.224 3.768a14.5 14.5 0 0 0-3.67-1.153c-.158.286-.343.67-.47.976a13.5 13.5 0 0 0-4.067 0c-.128-.306-.317-.69-.476-.976A14.4 14.4 0 0 0 3.868 3.77C1.546 7.28.916 10.703 1.231 14.077a14.7 14.7 0 0 0 4.5 2.306q.545-.748.965-1.587a9.5 9.5 0 0 1-1.518-.74q.191-.14.372-.293c2.927 1.369 6.107 1.369 8.999 0q.183.152.372.294-.723.437-1.52.74.418.838.963 1.588a14.6 14.6 0 0 0 4.504-2.308c.37-3.911-.63-7.302-2.644-10.309m-9.13 8.234c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.894 0 1.614.82 1.599 1.82.001 1-.705 1.82-1.6 1.82m5.91 0c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.893 0 1.614.82 1.599 1.82 0 1-.706 1.82-1.6 1.82"/>
</symbol>
<symbol id="documentation-icon" viewBox="0 0 21 20">
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="m15.5 13.333 1.533 1.322c.645.555.967.833.967 1.178s-.322.623-.967 1.179L15.5 18.333m-3.333-5-1.534 1.322c-.644.555-.966.833-.966 1.178s.322.623.966 1.179l1.534 1.321"/>
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M17.167 10.836v-4.32c0-1.41 0-2.117-.224-2.68-.359-.906-1.118-1.621-2.08-1.96-.599-.21-1.349-.21-2.848-.21-2.623 0-3.935 0-4.983.369-1.684.591-3.013 1.842-3.641 3.428C3 6.449 3 7.684 3 10.154v2.122c0 2.558 0 3.838.706 4.726q.306.383.713.671c.76.536 1.79.64 3.581.66"/>
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M3 10a2.78 2.78 0 0 1 2.778-2.778c.555 0 1.209.097 1.748-.047.48-.129.854-.503.982-.982.145-.54.048-1.194.048-1.749a2.78 2.78 0 0 1 2.777-2.777"/>
</symbol>
<symbol id="github-icon" viewBox="0 0 19 19">
<path fill="#08060d" fill-rule="evenodd" d="M9.356 1.85C5.05 1.85 1.57 5.356 1.57 9.694a7.84 7.84 0 0 0 5.324 7.44c.387.079.528-.168.528-.376 0-.182-.013-.805-.013-1.454-2.165.467-2.616-.935-2.616-.935-.349-.91-.864-1.143-.864-1.143-.71-.48.051-.48.051-.48.787.051 1.2.805 1.2.805.695 1.194 1.817.857 2.268.649.064-.507.27-.857.49-1.052-1.728-.182-3.545-.857-3.545-3.87 0-.857.31-1.558.8-2.104-.078-.195-.349-1 .077-2.078 0 0 .657-.208 2.14.805a7.5 7.5 0 0 1 1.946-.26c.657 0 1.328.092 1.946.26 1.483-1.013 2.14-.805 2.14-.805.426 1.078.155 1.883.078 2.078.502.546.799 1.247.799 2.104 0 3.013-1.818 3.675-3.558 3.87.284.247.528.714.528 1.454 0 1.052-.012 1.896-.012 2.156 0 .208.142.455.528.377a7.84 7.84 0 0 0 5.324-7.441c.013-4.338-3.48-7.844-7.773-7.844" clip-rule="evenodd"/>
</symbol>
<symbol id="social-icon" viewBox="0 0 20 20">
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M12.5 6.667a4.167 4.167 0 1 0-8.334 0 4.167 4.167 0 0 0 8.334 0"/>
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M2.5 16.667a5.833 5.833 0 0 1 8.75-5.053m3.837.474.513 1.035c.07.144.257.282.414.309l.93.155c.596.1.736.536.307.965l-.723.73a.64.64 0 0 0-.152.531l.207.903c.164.715-.213.991-.84.618l-.872-.52a.63.63 0 0 0-.577 0l-.872.52c-.624.373-1.003.094-.84-.618l.207-.903a.64.64 0 0 0-.152-.532l-.723-.729c-.426-.43-.289-.864.306-.964l.93-.156a.64.64 0 0 0 .412-.31l.513-1.034c.28-.562.735-.562 1.012 0"/>
</symbol>
<symbol id="x-icon" viewBox="0 0 19 19">
<path fill="#08060d" fill-rule="evenodd" d="M1.893 1.98c.052.072 1.245 1.769 2.653 3.77l2.892 4.114c.183.261.333.48.333.486s-.068.089-.152.183l-.522.593-.765.867-3.597 4.087c-.375.426-.734.834-.798.905a1 1 0 0 0-.118.148c0 .01.236.017.664.017h.663l.729-.83c.4-.457.796-.906.879-.999a692 692 0 0 0 1.794-2.038c.034-.037.301-.34.594-.675l.551-.624.345-.392a7 7 0 0 1 .34-.374c.006 0 .93 1.306 2.052 2.903l2.084 2.965.045.063h2.275c1.87 0 2.273-.003 2.266-.021-.008-.02-1.098-1.572-3.894-5.547-2.013-2.862-2.28-3.246-2.273-3.266.008-.019.282-.332 2.085-2.38l2-2.274 1.567-1.782c.022-.028-.016-.03-.65-.03h-.674l-.3.342a871 871 0 0 1-1.782 2.025c-.067.075-.405.458-.75.852a100 100 0 0 1-.803.91c-.148.172-.299.344-.99 1.127-.304.343-.32.358-.345.327-.015-.019-.904-1.282-1.976-2.808L6.365 1.85H1.8zm1.782.91 8.078 11.294c.772 1.08 1.413 1.973 1.425 1.984.016.017.241.02 1.05.017l1.03-.004-2.694-3.766L7.796 5.75 5.722 2.852l-1.039-.004-1.039-.004z" clip-rule="evenodd"/>
</symbol>
</svg>

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -1,33 +0,0 @@
[package]
name = "app"
version = "0.1.0"
description = "WW додепчик"
authors = ["KPTL"]
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"
tauri-plugin-process = "2"
windows = { version = "0.52", features = ["Win32_UI_Shell"] }
tauri-plugin-opener = "2"
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
tauri-plugin-global-shortcut = "2"
tauri-plugin-single-instance = "2"
tauri-plugin-updater = "2"

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSCameraUsageDescription</key>
<string>Request camera access for WebRTC</string>
<key>NSMicrophoneUsageDescription</key>
<string>Request microphone access for WebRTC</string>
</dict>
</plist>

View File

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

View File

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

View File

@@ -1,20 +0,0 @@
{
"identifier": "desktop-capability",
"platforms": [
"macOS",
"windows",
"linux"
],
"windows": [
"main"
],
"permissions": [
"updater:default",
"global-shortcut:allow-is-registered",
"global-shortcut:allow-register",
"global-shortcut:allow-unregister",
"global-shortcut:allow-unregister-all",
"opener:allow-default-urls",
"opener:allow-open-url"
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 403 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 758 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 391 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 540 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 812 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1009 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 561 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 570 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 570 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 584 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 584 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 332 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 558 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 558 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 805 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 461 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 739 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 739 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 558 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 997 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 997 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 979 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -1,3 +0,0 @@
<svg width="256" height="256" viewBox="0 0 256 256" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M232.899 20C237.318 20.0002 240.899 23.5819 240.899 28V227.644C240.899 234.599 232.635 238.241 227.501 233.548L202.03 210.261C200.556 208.913 198.63 208.165 196.632 208.165H23.1006C18.6825 208.165 15.1006 204.583 15.1006 200.165V28C15.1006 23.5819 18.6825 20.0002 23.1006 20H232.899ZM129.758 58.3818C120.029 58.3818 111.244 60.5556 103.403 64.9033C95.5633 69.251 89.3442 75.6118 84.7471 83.9863C80.1499 92.3611 77.8516 102.572 77.8516 114.617C77.8516 126.627 80.1147 136.82 84.6406 145.194C89.1665 153.569 95.3323 159.948 103.137 164.331C110.977 168.679 119.851 170.853 129.758 170.853C137.277 170.852 143.941 169.712 149.75 167.432C155.594 165.151 160.548 162.086 164.61 158.237C168.673 154.353 171.863 150.059 174.18 145.354C175.83 142.054 177.015 138.719 177.735 135.349C178.227 133.051 176.378 131.016 174.028 131.002L155.054 130.888C153.103 130.876 151.468 132.29 150.861 134.145C150.415 135.508 149.849 136.786 149.162 137.978C147.986 140.044 146.471 141.808 144.618 143.27C142.801 144.695 140.68 145.782 138.257 146.53C135.869 147.279 133.214 147.653 130.292 147.653C125.089 147.653 120.581 146.424 116.768 143.965C112.99 141.47 110.05 137.782 107.947 132.899C105.88 127.981 104.847 121.887 104.847 114.617C104.847 107.632 105.862 101.681 107.894 96.7627C109.961 91.8448 112.901 88.0849 116.714 85.4834C120.563 82.8819 125.142 81.5811 130.452 81.5811C133.446 81.5811 136.172 82.009 138.631 82.8643C141.125 83.6839 143.282 84.8773 145.1 86.4453C146.917 88.0134 148.378 89.9028 149.482 92.1123C150.104 93.3561 150.607 94.6845 150.992 96.0977C151.52 98.0371 153.178 99.542 155.188 99.542H173.992C176.355 99.5418 178.218 97.5003 177.806 95.1738C176.953 90.3679 175.494 85.9973 173.431 82.0625C170.758 76.9664 167.283 72.6721 163.007 69.1797C158.73 65.6516 153.777 62.9786 148.146 61.1611C142.516 59.308 136.386 58.3819 129.758 58.3818Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -1,21 +0,0 @@
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_opener::init())
.plugin(tauri_plugin_global_shortcut::Builder::new().build())
.plugin(tauri_plugin_process::init())
.plugin(tauri_plugin_updater::Builder::new().build())
// .plugin(tauri_plugin_single_instance::init(|_, _, _| {}))
.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

@@ -1,21 +0,0 @@
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
#[cfg(target_os = "windows")]
fn set_app_user_model_id() {
use windows::core::HSTRING;
use windows::Win32::UI::Shell::SetCurrentProcessExplicitAppUserModelID;
unsafe {
SetCurrentProcessExplicitAppUserModelID(&HSTRING::from("xyz.koptilnya.chad"))
.ok()
.expect("Failed to set AppUserModelID");
}
}
fn main() {
#[cfg(target_os = "windows")]
set_app_user_model_id();
app_lib::run();
}

View File

@@ -1 +0,0 @@
{"rustc_fingerprint":1074701663444030447,"outputs":{"17747080675513052775":{"success":true,"status":"","code":0,"stdout":"rustc 1.95.0 (59807616e 2026-04-14)\nbinary: rustc\ncommit-hash: 59807616e1fa2540724bfbac14d7976d7e4a3860\ncommit-date: 2026-04-14\nhost: x86_64-pc-windows-msvc\nrelease: 1.95.0\nLLVM version: 22.1.2\n","stderr":""},"7971740275564407648":{"success":true,"status":"","code":0,"stdout":"___.exe\nlib___.rlib\n___.dll\n___.dll\n___.lib\n___.dll\nC:\\Users\\opti\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\npacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"msvc\"\ntarget_family=\"windows\"\ntarget_feature=\"cmpxchg16b\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_feature=\"sse3\"\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"windows\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"pc\"\nwindows\n","stderr":""}},"successes":{}}

View File

@@ -1 +0,0 @@
{"rustc":8891013984288978370,"features":"[]","declared_features":"[]","target":12687594469746301899,"profile":8731458305071235362,"path":4942398508502643691,"deps":[[1322478694103194923,"app_lib",false,8070585750093435046],[1322478694103194923,"build_script_build",false,16691984141835454783],[2700615264719386388,"tauri_plugin_opener",false,7350390124577390804],[4736393929136623228,"tauri_plugin_global_shortcut",false,15267933955632970549],[5673630358394410545,"tauri_plugin_updater",false,14019643380268120922],[8695090098768911186,"windows",false,17298248671909505349],[10630857666389190470,"log",false,5016507518680283320],[12653526805862679340,"tauri_plugin_log",false,15855325777720298125],[13548984313718623784,"serde",false,7298479236282139191],[13795362694956882968,"serde_json",false,4974751760879812175],[13905323280135927163,"tauri_plugin_single_instance",false,10523578089830730283],[14261240476176424521,"tauri",false,8738078672178348289],[18393575805749125025,"tauri_plugin_process",false,17190748950968290852]],"local":[{"CheckDepInfo":{"dep_info":"debug\\.fingerprint\\app-4e7dc2d6835c5d74\\dep-bin-app","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0}

View File

@@ -1,60 +0,0 @@
{
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"productName": "Chad",
"version": "0.3.0-rc.3",
"identifier": "xyz.koptilnya.chad",
"build": {
"frontendDist": "../dist",
"devUrl": "http://localhost:3000",
"beforeDevCommand": "yarn dev",
"beforeBuildCommand": "yarn generate"
},
"app": {
"windows": [
{
"maximizable": true,
"label": "main",
"title": "Chad",
"width": 800,
"height": 600,
"minWidth": 800,
"minHeight": 600,
"resizable": true,
"fullscreen": false,
"center": true,
"theme": "Dark",
"additionalBrowserArgs": "--disable-features=msWebOOUI,msPdfOOUI,msSmartScreenProtection --autoplay-policy=no-user-gesture-required --lang=en",
"incognito": false
}
],
"security": {
"csp": null,
"capabilities": []
}
},
"bundle": {
"createUpdaterArtifacts": true,
"active": true,
"targets": ["nsis"],
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
],
"windows": {
"nsis": {
"installerIcon": "icons/icon.ico"
}
}
},
"plugins": {
"updater": {
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEU3MzkxMzM3RkQ3NTg4QUQKUldTdGlIWDlOeE01NStIak9VbmZTTm9HY2NyNUQrVXB5ZEdIN1BkK2lhYW9zWkNCQnZQSjRmelIK",
"endpoints": [
"https://git.koptilnya.xyz/opti1337/chad/releases/download/latest/updater.json"
]
}
}
}

View File

@@ -1,23 +0,0 @@
<template>
<Component :is="layoutComponent">
<RouterView />
</Component>
<ChadDialogContainer />
</template>
<script setup lang="ts">
import ChadDialogContainer from '@shared/components/ui/DialogContainer.vue'
import DefaultLayout from '@shared/layouts/Default.vue'
import { computed } from 'vue'
import { useRoute } from 'vue-router'
const route = useRoute()
const layoutComponent = computed(() => {
return route.meta.layout ?? DefaultLayout
})
</script>
<style lang="scss">
</style>

View File

@@ -1,42 +0,0 @@
<template>
<div class="error-app">
<img class="error-app__image" src="/sad-pepe.png" alt="Oops!" draggable="false">
<p class="error-app__message">
{{ message }}
</p>
</div>
</template>
<script setup lang="ts">
defineProps<{
message: string
}>()
</script>
<style lang="scss">
.error-app {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
&__image {
width: 120px;
margin-bottom: var(--space-6);
user-select: none;
opacity: 0.9;
}
&__message {
@include font-body-bold;
padding: var(--space-2) var(--space-3);
background-color: var(--paper);
outline: var(--border-w) solid var(--ink);
outline-offset: calc(var(--border-w) * -1);
box-shadow: var(--shadow);
}
}
</style>

View File

@@ -1,29 +0,0 @@
<template>
<div class="preloader-app">
<p>
Loading...
</p>
</div>
</template>
<script setup lang="ts">
</script>
<style lang="scss">
.preloader-app {
display: flex;
height: 100%;
> p {
@include font-body-bold;
margin: auto;
padding: var(--space-2) var(--space-3);
background-color: var(--paper);
outline: var(--border-w) solid var(--ink);
outline-offset: calc(var(--border-w) * -1);
box-shadow: var(--shadow);
}
}
</style>

View File

@@ -1,34 +0,0 @@
<template>
<div class="updater-app">
<p v-if="checking">
Checking updates...
</p>
<p v-else-if="!!lastUpdate">
Update available: {{ lastUpdate.version }}
</p>
</div>
</template>
<script setup lang="ts">
import { useUpdater } from '@shared/composables/use-updater'
const { checking, lastUpdate } = useUpdater()
</script>
<style lang="scss">
.updater-app {
display: flex;
height: 100%;
> p {
@include font-body-bold;
margin: auto;
padding: var(--space-2) var(--space-3);
background-color: var(--paper);
outline: var(--border-w) solid var(--ink);
outline-offset: calc(var(--border-w) * -1);
box-shadow: var(--shadow);
}
}
</style>

Some files were not shown because too many files have changed in this diff Show More