Working on better thing

This commit is contained in:
Fabian Stamm
2023-07-02 15:51:49 +02:00
parent a9767da606
commit 8aa6d43483
35 changed files with 6591 additions and 1234 deletions

View File

@ -0,0 +1,15 @@
module.exports = {
"pages": "src/pages",
"sourceDir": "public",
"routifyDir": "src/.routify",
"ignore": "",
"dynamicImports": true,
"singleBuild": false,
"noHashScroll": false,
"distDir": "dist",
"hashScroll": true,
"extensions": [
"svelte"
],
"started": "2022-02-17T23:53:42.346Z"
}

View File

@ -0,0 +1,140 @@
/**
* @roxi/routify 2.18.4
* File generated Thu Feb 17 2022 23:53:42 GMT+0000 (Coordinated Universal Time)
*/
export const __version = "2.18.4"
export const __timestamp = "2022-02-17T23:53:42.361Z"
//buildRoutes
import { buildClientTree } from "@roxi/routify/runtime/buildRoutes"
//imports
//options
export const options = {}
//tree
export const _tree = {
"name": "root",
"filepath": "/",
"root": true,
"ownMeta": {},
"absolutePath": "src/pages",
"children": [
{
"isFile": true,
"isDir": false,
"file": "index.svelte",
"filepath": "/index.svelte",
"name": "index",
"ext": "svelte",
"badExt": false,
"absolutePath": "/root/Projects/ScreenSharingThing/Client/src/pages/index.svelte",
"importPath": "../pages/index.svelte",
"isLayout": false,
"isReset": false,
"isIndex": true,
"isFallback": false,
"isPage": true,
"ownMeta": {},
"meta": {
"recursive": true,
"preload": false,
"prerender": true
},
"path": "/index",
"id": "_index",
"component": () => import('../pages/index.svelte').then(m => m.default)
},
{
"isFile": false,
"isDir": true,
"file": "session",
"filepath": "/session",
"name": "session",
"ext": "",
"badExt": false,
"absolutePath": "/root/Projects/ScreenSharingThing/Client/src/pages/session",
"children": [
{
"isFile": false,
"isDir": true,
"file": "[sessionid]",
"filepath": "/session/[sessionid]",
"name": "[sessionid]",
"ext": "",
"badExt": false,
"absolutePath": "/root/Projects/ScreenSharingThing/Client/src/pages/session/[sessionid]",
"children": [
{
"isFile": true,
"isDir": false,
"file": "index.svelte",
"filepath": "/session/[sessionid]/index.svelte",
"name": "index",
"ext": "svelte",
"badExt": false,
"absolutePath": "/root/Projects/ScreenSharingThing/Client/src/pages/session/[sessionid]/index.svelte",
"importPath": "../pages/session/[sessionid]/index.svelte",
"isLayout": false,
"isReset": false,
"isIndex": true,
"isFallback": false,
"isPage": true,
"ownMeta": {},
"meta": {
"recursive": true,
"preload": false,
"prerender": true
},
"path": "/session/:sessionid/index",
"id": "_session__sessionid_index",
"component": () => import('../pages/session/[sessionid]/index.svelte').then(m => m.default)
}
],
"isLayout": false,
"isReset": false,
"isIndex": false,
"isFallback": false,
"isPage": false,
"ownMeta": {},
"meta": {
"recursive": true,
"preload": false,
"prerender": true
},
"path": "/session/:sessionid"
}
],
"isLayout": false,
"isReset": false,
"isIndex": false,
"isFallback": false,
"isPage": false,
"ownMeta": {},
"meta": {
"recursive": true,
"preload": false,
"prerender": true
},
"path": "/session"
}
],
"isLayout": false,
"isReset": false,
"isIndex": false,
"isFallback": false,
"meta": {
"recursive": true,
"preload": false,
"prerender": true
},
"path": "/"
}
export const {tree, routes} = buildClientTree(_tree)

View File

@ -0,0 +1,3 @@
[
"/index"
]

6
Client/src/App.svelte Normal file
View File

@ -0,0 +1,6 @@
<script lang="ts">
import { Router } from "@roxi/routify";
import { routes } from "./.routify/routes";
</script>
<Router {routes} />

105
Client/src/api.ts Normal file
View File

@ -0,0 +1,105 @@
import {
type ICollectionRef,
type IDocumentRef,
UpdateTypes,
} from "@rtdb2/sdk";
import { nanoid } from "nanoid";
import { Peer } from "peerjs/lib/peer";
import {
collectionToStore,
Sessions,
type IMember,
type IMessage,
type ISession,
} from "./db";
import type { Readable } from "svelte/store";
import { Signal } from "@hibas123/utils";
export class Session {
#client_id = nanoid(22);
#peer: Peer;
#session: IDocumentRef<ISession>;
#members: ICollectionRef<IMember>;
#messages: ICollectionRef<IMessage>;
#self: IDocumentRef<IMember>;
#name: string;
#iv: any;
#closeSignal = new Signal();
members: Readable<(IMember & { $id: string })[]>;
messages: Readable<(IMessage & { $id: string })[]>;
get name() {
return this.#name;
}
set name(value) {
this.#name = value;
this.#self.update({ name: UpdateTypes.Value(value) });
}
constructor(id: string, name: string) {
this.#name = name;
this.#peer = new Peer(this.#client_id, {
host: window.location.hostname,
port: window.location.port as any,
path: "/peerjs",
config: {},
});
this.#session = Sessions.doc(id);
this.#members = this.#session.collection("members");
this.#messages = this.#session.collection("messages");
this.#self = this.#members.doc(this.#client_id);
this.members = collectionToStore(this.#members);
this.messages = collectionToStore(this.#messages);
this.registerSelf();
this.#iv = setInterval(() => this.tick(), 5000);
}
tick() {
this.#self.update({ lastActive: UpdateTypes.Value(Date.now()) });
}
registerSelf() {
this.#self.set({
name: this.#name,
lastActive: Date.now(),
offline: false,
});
}
close() {
this.#closeSignal.sendSignal();
clearInterval(this.#iv);
this.#self.update({ offline: UpdateTypes.Value(true) });
this.#peer.destroy();
}
}
let bitrate = new URL(window.location.href).searchParams.get("br") || 50000;
function bitrateTransform(sdp: string) {
var arr = sdp.split("\r\n");
arr.forEach((str, i) => {
if (/^a=fmtp:\d*/.test(str)) {
console.log("found fmtp");
arr[i] =
str +
`;x-google-max-bitrate=${bitrate};x-google-min-bitrate=0;x-google-start-bitrate=12000`;
} else if (/^a=mid:(1|video)/.test(str)) {
console.log("found mid");
arr[i] += "\r\nb=AS:" + bitrate;
}
});
let res = arr.join("\r\n");
console.log(sdp, res);
return res;
}

5
Client/src/bootstrap.ts Normal file
View File

@ -0,0 +1,5 @@
import App from "./App.svelte";
new App({
target: document.body,
});

43
Client/src/db.ts Normal file
View File

@ -0,0 +1,43 @@
import { AwaitStore } from "@hibas123/utils";
import Client, { type ICollectionRef } from "@rtdb2/sdk";
import { readable } from "svelte/store";
const client = new Client(
"https://rtdb.hibas123.de",
"screen_share",
"screen_share"
);
(window as any).db = client;
export const Sessions = client.collection<ISession>("sessions");
export interface ISession {}
export interface IMember {
lastActive: number;
offline: boolean;
name: string;
}
export interface IMessage {
sender: string;
message: string;
}
export function collectionToStore<T>(coll: ICollectionRef<T>) {
return readable<(T & { $id: string })[]>([], (set) => {
const cancel = new AwaitStore(false);
(async () => {
const itr = await coll.onSnapshot();
cancel.awaitValue(true).then(() => itr.close());
for await (const snapshot of itr) {
set(snapshot.docs.map((doc) => ({ ...doc.data(), $id: doc.id })));
}
})();
return () => {
cancel.send(true);
};
});
}

View File

@ -0,0 +1,80 @@
<script lang="ts">
import Button from "@smui/button";
import Textfield from "@smui/textfield";
import Paper, { Title as PTitle, Content as PContent } from "@smui/paper";
import { nanoid } from "nanoid";
import { url } from "@roxi/routify";
import Snackbar, { Actions, Label } from "@smui/snackbar";
import type { SnackbarComponentDev } from "@smui/snackbar";
import IconButton from "@smui/icon-button";
let sessionID = "";
let errorSnack: SnackbarComponentDev;
function create() {
sessionID = nanoid(22);
connect();
}
function connect() {
if (sessionID.length < 22) {
errorSnack.open();
return;
}
window.history.pushState(
undefined,
undefined,
$url(`/session/${sessionID}`)
);
sessionID = "";
}
</script>
<div class="outer">
<div class="inner">
<Paper elevation={6}>
<PContent>
<PTitle>Create Session</PTitle>
<div style="margin-top: 1rem" />
<Button variant="raised" on:click={create}>Create</Button>
</PContent>
</Paper>
<Paper elevation={6}>
<PContent>
<PTitle>Join Session</PTitle>
<Textfield
label="Session ID"
bind:value={sessionID}
style="width: 100%;"
/>
<div style="margin-top: 1rem" />
<Button variant="raised" on:click={connect}>Connect</Button>
</PContent>
</Paper>
</div>
</div>
<Snackbar bind:this={errorSnack}>
<Label>Invalid Session!</Label>
<Actions>
<IconButton class="material-icons" title="Dismiss">close</IconButton>
</Actions>
</Snackbar>
<style>
.outer {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
}
.inner {
display: grid;
grid-template-columns: repeat(2, minmax(150px, 300px));
grid-template-rows: auto;
gap: 1rem;
}
</style>

View File

@ -0,0 +1,42 @@
<script lang="ts">
import { onMount } from "svelte";
import { Session } from "../../../api";
export let sessionid: string;
let session = new Session(sessionid, "");
let members = session.members;
onMount(() => {
return () => {
session.close();
};
});
</script>
<!-- {sessionid} -->
<div class="outer">
<div class="members">
{#each $members as member (member.$id)}
<div class="member">
<div class="name">{member.name || "anon"}</div>
<div class="id">{member.$id}</div>
</div>
{/each}
</div>
<div class="content">Content</div>
</div>
<style>
.outer {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: grid;
grid-template-columns: 200px 1fr;
}
</style>

View File

@ -0,0 +1,28 @@
@use "sass:color";
@use "@material/theme/color-palette";
// Svelte Colors!
@use "@material/theme/index" as theme with
(
$primary: #1e88e5,
$secondary: #d8701b,
$surface: #fff,
$background: #fff,
$error: color-palette.$red-900
);
@import "@material/typography/mdc-typography";
// html,
// body {
// background-color: theme.$surface;
// color: theme.$on-surface;
// }
// a {
// color: #40b3ff;
// }
// a:visited {
// color: color.scale(#40b3ff, $lightness: -35%);
// }

View File

@ -0,0 +1,28 @@
@use "sass:color";
@use "@material/theme/color-palette";
// Svelte Colors! (Dark Theme)
@use "@material/theme/index" as theme with
(
$primary: #1e88e5,
$secondary: #d8701b,
$surface: color.adjust(color-palette.$grey-900, $blue: +4),
$background: #000,
$error: color-palette.$red-700
);
@import "@material/typography/mdc-typography";
// html,
// body {
// background-color: #000;
// color: theme.$on-surface;
// }
// a {
// color: #40b3ff;
// }
// a:visited {
// color: color.scale(#40b3ff, $lightness: -35%);
// }