Skip to content
Snippets Groups Projects
Commit 694bfe0b authored by Jonas Zohren's avatar Jonas Zohren :speech_balloon:
Browse files

add online_status_list

parent 52760140
No related branches found
No related tags found
No related merge requests found
Pipeline #8003 passed with warnings
Showing
with 1787 additions and 0 deletions
{
"svelteSortOrder": "styles-scripts-markup",
"svelteStrictMode": true,
"svelteBracketNewLine": true,
"svelteAllowShorthand": false,
"svelteIndentScriptAndStyle": false
}
*Looking for a shareable component template? Go here --> [sveltejs/component-template](https://github.com/sveltejs/component-template)*
---
# svelte app
This is a project template for [Svelte](https://svelte.dev) apps. It lives at https://github.com/sveltejs/template.
To create a new project based on this template using [degit](https://github.com/Rich-Harris/degit):
```bash
npx degit sveltejs/template svelte-app
cd svelte-app
```
*Note that you will need to have [Node.js](https://nodejs.org) installed.*
## Get started
Install the dependencies...
```bash
cd svelte-app
npm install
```
...then start [Rollup](https://rollupjs.org):
```bash
npm run dev
```
Navigate to [localhost:5000](http://localhost:5000). You should see your app running. Edit a component file in `src`, save it, and reload the page to see your changes.
By default, the server will only respond to requests from localhost. To allow connections from other computers, edit the `sirv` commands in package.json to include the option `--host 0.0.0.0`.
If you're using [Visual Studio Code](https://code.visualstudio.com/) we recommend installing the official extension [Svelte for VS Code](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). If you are using other editors you may need to install a plugin in order to get syntax highlighting and intellisense.
## Building and running in production mode
To create an optimised version of the app:
```bash
npm run build
```
You can run the newly built app with `npm run start`. This uses [sirv](https://github.com/lukeed/sirv), which is included in your package.json's `dependencies` so that the app will work when you deploy to platforms like [Heroku](https://heroku.com).
## Single-page app mode
By default, sirv will only respond to requests that match files in `public`. This is to maximise compatibility with static fileservers, allowing you to deploy your app anywhere.
If you're building a single-page app (SPA) with multiple routes, sirv needs to be able to respond to requests for *any* path. You can make it so by editing the `"start"` command in package.json:
```js
"start": "sirv public --single"
```
## Using TypeScript
This template comes with a script to set up a TypeScript development environment, you can run it immediately after cloning the template with:
```bash
node scripts/setupTypeScript.js
```
Or remove the script via:
```bash
rm scripts/setupTypeScript.js
```
## Deploying to the web
### With [Vercel](https://vercel.com)
Install `vercel` if you haven't already:
```bash
npm install -g vercel
```
Then, from within your project folder:
```bash
cd public
vercel deploy --name my-project
```
### With [surge](https://surge.sh/)
Install `surge` if you haven't already:
```bash
npm install -g surge
```
Then, from within your project folder:
```bash
npm run build
surge public my-project.surge.sh
```
This diff is collapsed.
{
"name": "svelte-app",
"version": "1.0.0",
"scripts": {
"build": "rollup -c",
"dev": "rollup -c -w",
"start": "sirv public",
"validate": "svelte-check"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^14.0.0",
"@rollup/plugin-node-resolve": "^8.0.0",
"@rollup/plugin-typescript": "^6.0.0",
"@tsconfig/svelte": "^1.0.0",
"faker": "^5.1.0",
"prettier": "^2.1.2",
"prettier-plugin-svelte": "^1.4.0",
"rollup": "^2.3.4",
"rollup-plugin-livereload": "^2.0.0",
"rollup-plugin-svelte": "^6.0.0",
"rollup-plugin-terser": "^7.0.0",
"svelte": "^3.0.0",
"svelte-check": "^1.0.0",
"svelte-preprocess": "^4.0.0",
"tslib": "^2.0.0",
"typescript": "^3.9.3"
},
"dependencies": {
"@types/faker": "^5.1.2",
"sirv-cli": "^1.0.0"
}
}
This diff is collapsed.
online_status_list/public/favicon.png

3.05 KiB

html, body {
position: relative;
width: 100%;
height: 100%;
}
body {
color: #333;
margin: 0;
padding: 8px;
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
}
a {
color: rgb(0,100,200);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
a:visited {
color: rgb(0,80,160);
}
label {
display: block;
}
input, button, select, textarea {
font-family: inherit;
font-size: inherit;
-webkit-padding: 0.4em 0;
padding: 0.4em;
margin: 0 0 0.5em 0;
box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 2px;
}
input:disabled {
color: #ccc;
}
button {
color: #333;
background-color: #f4f4f4;
outline: none;
}
button:disabled {
color: #999;
}
button:not(:disabled):active {
background-color: #ddd;
}
button:focus {
border-color: #666;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>O-Phase WiSe 2020</title>
<link rel="icon" type="image/png" href="/favicon.png" />
<link rel="stylesheet" href="/global.css" />
<link rel="stylesheet" href="/build/bundle.css" />
<link rel="stylesheet" href="bulma.min.css" />
<script defer src="/build/bundle.js"></script>
</head>
<body></body>
</html>
[
{
"title": "Gruppen",
"url": "somerooms.json"
}
]
\ No newline at end of file
[{"uid":"fsr-n41-aby-yzk","url":"https://bbb.fachschaften.org/b/fsr-n41-aby-yzk","name":"Gruppe 01 (Basti & Marvin) - OPWiSe20","userCount":"2","users":[{"classes":["moderator","noVoice"],"name":"FSR Bot "},{"classes":["moderator","presenter","noVoice"],"name":"FSR Bot "}]},{"uid":"fsr-ocp-ymd-imd","url":"https://bbb.fachschaften.org/b/fsr-ocp-ymd-imd","name":"Gruppe 02 (Lukas & Marcel - OPWiSe20","userCount":"2","users":[{"classes":["moderator","noVoice"],"name":"FSR Bot "},{"classes":["moderator","presenter","noVoice"],"name":"FSR Bot "}]},{"uid":"fsr-7nh-gft-utw","url":"https://bbb.fachschaften.org/b/fsr-7nh-gft-utw","name":"Gruppe 03 (Zora & Jan) - OPWiSe20","userCount":"2","users":[{"classes":["moderator","noVoice"],"name":"FSR Bot "},{"classes":["moderator","presenter","noVoice"],"name":"FSR Bot "}]},{"uid":"fsr-sya-lwn-h4j","url":"https://bbb.fachschaften.org/b/fsr-sya-lwn-h4j","name":"Gruppe 04 (Anca & Tobias) - OPWiSe20","userCount":"2","users":[{"classes":["moderator","noVoice"],"name":"FSR Bot "},{"classes":["moderator","presenter","noVoice"],"name":"FSR Bot "}]},{"uid":"fsr-n2i-6op-n5f","url":"https://bbb.fachschaften.org/b/fsr-n2i-6op-n5f","name":"Gruppe 05 (Louis & Nico) - OPWiSe20","userCount":"2","users":[{"classes":["moderator","noVoice"],"name":"FSR Bot "},{"classes":["moderator","presenter","noVoice"],"name":"FSR Bot "}]},{"uid":"fsr-5l1-3wn-ucm","url":"https://bbb.fachschaften.org/b/fsr-5l1-3wn-ucm","name":"Gruppe 06 (Nicolas & Lara) - OPWiSe20","userCount":"2","users":[{"classes":["moderator","noVoice"],"name":"FSR Bot "},{"classes":["moderator","presenter","noVoice"],"name":"FSR Bot "}]},{"uid":"fsr-gel-qu5-vq5","url":"https://bbb.fachschaften.org/b/fsr-gel-qu5-vq5","name":"Gruppe 07 (Molly & Theo) - OPWiSe20","userCount":"2","users":[{"classes":["moderator","noVoice"],"name":"FSR Bot "},{"classes":["moderator","presenter","noVoice"],"name":"FSR Bot "}]},{"uid":"fsr-1vq-taq-bc8","url":"https://bbb.fachschaften.org/b/fsr-1vq-taq-bc8","name":"Gruppe 08 (Julian & Hauer) - OPWiSe20","userCount":"2","users":[{"classes":["moderator","noVoice"],"name":"FSR Bot "},{"classes":["moderator","presenter","noVoice"],"name":"FSR Bot "}]},{"uid":"fsr-due-fqc-h8y","url":"https://bbb.fachschaften.org/b/fsr-due-fqc-h8y","name":"Gruppe 09 (Master mit Hauer) - OPWiSe20","userCount":"2","users":[{"classes":["moderator","noVoice"],"name":"FSR Bot "},{"classes":["moderator","presenter","noVoice"],"name":"FSR Bot "}]},{"uid":"fsr-cui-nit-ydi","url":"https://bbb.fachschaften.org/b/fsr-cui-nit-ydi","name":"Gruppe 10 (Lehramt mit AmYu) - OPWiSe20","userCount":"2","users":[{"classes":["moderator","noVoice"],"name":"FSR Bot "},{"classes":["moderator","presenter","noVoice"],"name":"FSR Bot "}]}]
\ No newline at end of file
import svelte from 'rollup-plugin-svelte';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import livereload from 'rollup-plugin-livereload';
import { terser } from 'rollup-plugin-terser';
import sveltePreprocess from 'svelte-preprocess';
import typescript from '@rollup/plugin-typescript';
const production = !process.env.ROLLUP_WATCH;
function serve() {
let server;
function toExit() {
if (server) server.kill(0);
}
return {
writeBundle() {
if (server) return;
server = require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
stdio: ['ignore', 'inherit', 'inherit'],
shell: true
});
process.on('SIGTERM', toExit);
process.on('exit', toExit);
}
};
}
export default {
input: 'src/main.ts',
output: {
sourcemap: true,
format: 'iife',
name: 'app',
file: 'public/build/bundle.js'
},
plugins: [
svelte({
// enable run-time checks when not in production
dev: !production,
// we'll extract any component CSS out into
// a separate file - better for performance
css: css => {
css.write('bundle.css');
},
preprocess: sveltePreprocess(),
}),
// If you have external dependencies installed from
// npm, you'll most likely need these plugins. In
// some cases you'll need additional configuration -
// consult the documentation for details:
// https://github.com/rollup/plugins/tree/master/packages/commonjs
resolve({
browser: true,
dedupe: ['svelte']
}),
commonjs(),
typescript({
sourceMap: !production,
inlineSources: !production
}),
// In dev mode, call `npm run start` once
// the bundle has been generated
!production && serve(),
// Watch the `public` directory and refresh the
// browser on changes when not in production
!production && livereload('public'),
// If we're building for production (npm run build
// instead of npm run dev), minify
production && terser()
],
watch: {
clearScreen: false
}
};
<script lang="ts">
import RoomOnlineListPanel from './RoomOnlineListPanel.svelte';
import { roomSets } from './stores.js';
async function fetchRoomData(): Promise<{sets: [{title: string, rooms: [{url: string, name: string, users: string[]}]}]}> {
const response = await fetch('mockdata.json')
const data = await response.json();
return data;
}
</script>
<section class="section">
<div class="container">
<div class="columns">
<div class="column">
<h1>
O-Phase WinterSemester 2020
</h1>
<h2>
Hier findet ihr eine Überischt über die einzelnen BBB-Räume und ihren Belegungsstatus.
</h2>
</div>
</div>
{#each $roomSets as roomSet (roomSet.title)}
<div class="column is-4">
<RoomOnlineListPanel {...roomSet} />
</div>
{/each}
</div>
</section>
<style>
main {
text-align: center;
padding: 1em;
max-width: 240px;
margin: 0 auto;
}
h1 {
color: #ff3e00;
text-transform: uppercase;
font-size: 4em;
font-weight: 100;
}
@media (min-width: 640px) {
main {
max-width: none;
}
}
</style>
\ No newline at end of file
<script lang="ts">
import SingleRoomPanelBlock from "./SingleRoomPanelBlock.svelte";
interface User {
classes: string[];
name: string;
}
interface Room {
uid: string;
url: string;
name: string;
userCount: number;
users: User[];
}
export let title: string;
export let rooms: Room[];
</script>
<nav class="panel is-primary">
<p class="panel-heading">{title}</p>
{#each rooms as room (room.url)}
<SingleRoomPanelBlock {...room} />
{/each}
</nav>
<script lang="ts">
export let name: string = "";
export let users: User[] = [];
export let url: string;
interface User {
classes: string[];
name: string;
}
$: displayTitle = name.replace(' - OPWiSe20','');
$: hasOnlineUsers = users.length !== 0;
$: leftList = users.slice(0, 4);
$: rightList = users.length === 8 ? users.slice(4, 8) : users.slice(4, 7);
$: hasOverflow = users.length > 8;
$: unlistedUserCount = users.length - 7;
</script>
<div class="panel-block">
<details style="width: 100%" open="{false}">
<summary>
<b>{displayTitle}</b>
({users.length}
👤)
<a href="{url}"><span
class="tag is-link is-light is-rounded"
>Betreten</span></a>
</summary>
{#if hasOnlineUsers}
<div class="columns" style="width: 100%">
<div class="column is-6">
<ul>
{#each leftList as user}
<li>{user.name}</li>
{/each}
</ul>
</div>
<div class="column is-6">
<ul>
{#each rightList as user}
<li>{user.name}</li>
{/each}
{#if hasOverflow}
<li><i>... {unlistedUserCount} weitere Benutzer</i></li>
{/if}
</ul>
</div>
</div>
{:else}<i>This room is currently empty.</i>{/if}
</details>
</div>
import App from './App.svelte';
const app = new App({
target: document.body,
props: {
name: 'world'
}
});
export default app;
\ No newline at end of file
const ROOM_SET_LIST_URL = "roomSets.json";
const ROOM_SET_LIST_UPDATE_INTERVAL = 20000;
const ROOM_SETS_UPDATE_INTERVAL = 1000;
import { readable } from "svelte/store";
interface RoomSetPointer {
title: string;
url: string;
}
interface User {
classes: string[];
name: string;
}
interface Room {
uid: string;
url: string;
name: string;
userCount: number;
users: User[];
}
interface RoomSet {
title: string;
rooms: Room[];
}
let stateRoomSetUrls: RoomSetPointer[] = [];
let stateRoomSets: RoomSet[] = [];
let updateRoomSetsListLock = false;
async function updateRoomSetsList(): Promise<void> {
try {
if (updateRoomSetsListLock) return;
updateRoomSetsListLock = true;
const response = await fetch(ROOM_SET_LIST_URL);
const data: RoomSetPointer[] = await response.json();
stateRoomSetUrls = data;
updateRoomSetsListLock = false;
} catch (error) {
updateRoomSetsListLock = false;
console.error("Error trying to fetch an updated list of roomSets.", error);
}
}
let updateRoomSetLocks: Map<string, boolean> = new Map();
async function updateRoomSet(roomSetUrl: string): Promise<Room[]> {
try {
if (updateRoomSetLocks[roomSetUrl]) return;
updateRoomSetLocks[roomSetUrl] = true;
const response = await fetch(roomSetUrl);
const data: Room[] = await response.json();
updateRoomSetLocks[roomSetUrl] = false;
return data;
} catch (error) {
updateRoomSetLocks[roomSetUrl] = false;
console.error(
"Error trying to fetch an updat for a room set from " + roomSetUrl + " .",
error
);
}
}
export const roomSets = readable(stateRoomSets, function start(set) {
updateRoomSetsList();
const roomSetsListRefreshInterval = setInterval(
updateRoomSetsList,
ROOM_SET_LIST_UPDATE_INTERVAL
);
const refreshRoomSets = async () => {
const newRoomSetsState: RoomSet[] = [];
for (const pointer of stateRoomSetUrls) {
const roomSetData = await updateRoomSet(pointer.url);
newRoomSetsState.push({
title: pointer.title,
rooms: roomSetData,
});
}
set(newRoomSetsState);
};
refreshRoomSets();
const roomSetsRefreshInteval = setInterval(
refreshRoomSets,
ROOM_SETS_UPDATE_INTERVAL
);
return function stop() {
clearInterval(roomSetsListRefreshInterval);
clearInterval(roomSetsRefreshInteval);
};
});
{
"extends": "@tsconfig/svelte/tsconfig.json",
"include": ["src/**/*"],
"exclude": ["node_modules/*", "__sapper__/*", "public/*"],
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment