up odj
This commit is contained in:
parent
08e645699c
commit
b56bd43ede
|
@ -2,8 +2,8 @@
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<main class="main">
|
<main class="main">
|
||||||
<div class="content">
|
<div class="content columns">
|
||||||
<div class="left-side">
|
<div class="left-side column is-4">
|
||||||
<strong>
|
<strong>
|
||||||
Sujets:
|
Sujets:
|
||||||
</strong>
|
</strong>
|
||||||
|
@ -11,34 +11,45 @@
|
||||||
<li class="subject" *ngFor="let s of subjects; index as i"
|
<li class="subject" *ngFor="let s of subjects; index as i"
|
||||||
[ngClass]="{ active: (currentSubjectId +1) == (i+1) }">
|
[ngClass]="{ active: (currentSubjectId +1) == (i+1) }">
|
||||||
<strong>{{ i + 1 }}) {{ s.title }}</strong>
|
<strong>{{ i + 1 }}) {{ s.title }}</strong>
|
||||||
<strong>
|
|
||||||
currentSubjectId: {{currentSubjectId}}
|
<p>{{ s.duration }} min, par {{ s.author }}. Reste: {{ resteTopicMinutes }}. Passé: {{s.spentSeconds}}. </p>
|
||||||
</strong>
|
<p *ngIf="s.finished">🎉</p>
|
||||||
<p>{{s.duration}} min, par {{s.author}}. Reste: {{resteTopicMinutes}}</p>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<textarea [(ngModel)]="pasteLand" id="pasteland" (ngModelChange)="parseTheListOfTopicsInPasteLand()"></textarea>
|
<textarea class="textarea mx-2 is-full" [(ngModel)]="pasteLand" id="pasteland" (ngModelChange)="parseTheListOfTopicsInPasteLand()"></textarea>
|
||||||
<pre>
|
<p>
|
||||||
{{hints}}
|
{{ (hints) }}
|
||||||
</pre>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="divider" role="separator" aria-label="Divider"></div>
|
<div class="right-side column is-8">
|
||||||
<div class="right-side">
|
<div class="pill-group"
|
||||||
<div class="pill-group">
|
[ngClass]="{
|
||||||
|
'topic-is-finished': subjects[currentSubjectId].finished || ! isTopicRunning(subjects[currentSubjectId])
|
||||||
|
}">
|
||||||
|
|
||||||
<h1 class="subject active">
|
<h1 class="subject active">
|
||||||
{{ subjects[currentSubjectId].title }}
|
{{ subjects[currentSubjectId].title }}
|
||||||
</h1>
|
</h1>
|
||||||
<p>{{ subjects[currentSubjectId].duration }} min, par {{ subjects[currentSubjectId].author }}</p>
|
<p>{{ subjects[currentSubjectId].duration }} min, par {{ subjects[currentSubjectId].author }}</p>
|
||||||
<!-- <p>Reste: {{resteTopicMinutes}}</p>-->
|
<p>Reste: {{ countRemainingMinutes(subjects[currentSubjectId]) }} min</p>
|
||||||
|
<p>avancement: {{ getPercentProgressTimeForTopic(subjects[currentSubjectId]) }} %</p>
|
||||||
|
|
||||||
<p>Début: {{ startTime }}</p>
|
<p>Début: {{ startTime }}</p>
|
||||||
<p>Fin: {{ endTime }}</p>
|
<p>Fin: {{ endTime }}</p>
|
||||||
|
|
||||||
<button class="btn btn-primary" (click)="nextSubject()">
|
<button class="btn btn-primary" (click)="previousSubject()">
|
||||||
|
précédent
|
||||||
|
</button>
|
||||||
|
<button class="btn is-primary" (click)="nextSubject()">
|
||||||
suivant
|
suivant
|
||||||
</button>
|
</button>
|
||||||
|
<button class="btn is-success" (click)="finishTopic(currentSubjectId)">
|
||||||
|
fini
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-primary" (click)="updateProgressEveryPeriod()">
|
||||||
|
up temps
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,13 +1,18 @@
|
||||||
import {Component, OnInit} from '@angular/core';
|
import {Component, OnDestroy, OnInit} from '@angular/core';
|
||||||
import {CommonModule} from '@angular/common';
|
import {CommonModule} from '@angular/common';
|
||||||
import {RouterOutlet} from '@angular/router';
|
import {RouterOutlet} from '@angular/router';
|
||||||
import {FormsModule} from "@angular/forms";
|
import {FormsModule} from "@angular/forms";
|
||||||
|
|
||||||
|
|
||||||
interface Subject {
|
interface Topic {
|
||||||
|
id: number, // numéro du sujet
|
||||||
title: string, // titre du sujet à aborder
|
title: string, // titre du sujet à aborder
|
||||||
duration: number, // nombre de minutes du sujet
|
duration: number, // nombre de minutes du sujet
|
||||||
author: string // auteur du sujet qui anime la discussion
|
author: string,// auteur du sujet qui anime la discussion
|
||||||
|
startDate: Date, // date de début du sujet
|
||||||
|
endDate: Date,// date de fin du sujet
|
||||||
|
finished: boolean,// si le sujet est terminé
|
||||||
|
spentSeconds: number, // nombre de secondes passées au sujet
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -17,18 +22,17 @@ interface Subject {
|
||||||
templateUrl: './app.component.html',
|
templateUrl: './app.component.html',
|
||||||
styleUrl: './app.component.scss',
|
styleUrl: './app.component.scss',
|
||||||
})
|
})
|
||||||
export class AppComponent implements OnInit {
|
export class AppComponent implements OnInit, OnDestroy {
|
||||||
title = 'odj';
|
title = 'odj';
|
||||||
subjects: any = [];
|
subjects: Array<Topic> = [];
|
||||||
currentSubjectId = 1;
|
currentSubjectId = 0;
|
||||||
startTime: string = "20:30";
|
// startTime: string = "20:30";
|
||||||
|
startTime: string = "17:00";
|
||||||
endTime: string = "22:00";
|
endTime: string = "22:00";
|
||||||
pasteLand: string = "* Présentation du suivi sur Nextcloud - 5min (tykayn)\n" +
|
pasteLand: string = "* Présentation du suivi sur Nextcloud - 5min (tykayn)\n" +
|
||||||
"* Réduction de bus factor - 5min (tykayn)\n" +
|
"* Réduction de bus factor - 5min (tykayn)\n" +
|
||||||
"* Réunion avec Wikimedia France - 5min (tykayn)\n" +
|
"* Réunion avec Wikimedia France - 5min (tykayn)\n" +
|
||||||
"* demande kit prise de vue Guyane https://forum.openstreetmap.fr/t/doter-osm-fr-d-appareils-de-prise-de-vues-de-photo-au-niveau-des-rues-pour-les-preter/9916/117 -> est-ce \"raisonnable\" d'en envoyer 1 ou n'est-il pas préférable d'en financer un pour la Guyane\n" +
|
"";
|
||||||
"* point sur l'organisation du SotM 2024 à Lyon - 15 min (renecha)\n" +
|
|
||||||
"* Budget pris en compte par l'association pour le SOTM-EU - Présentation des factures";
|
|
||||||
|
|
||||||
hints: string = " - le pad des notes de réunion https://annuel.framapad.org/p/N_IDAQXYLHswlpU2s3oE\n" +
|
hints: string = " - le pad des notes de réunion https://annuel.framapad.org/p/N_IDAQXYLHswlpU2s3oE\n" +
|
||||||
"\t - canal spécial pour le SOTM fr sur telegram https://t.me/SOTM2023-Marseille\n" +
|
"\t - canal spécial pour le SOTM fr sur telegram https://t.me/SOTM2023-Marseille\n" +
|
||||||
|
@ -39,34 +43,165 @@ export class AppComponent implements OnInit {
|
||||||
"\t - les réunions mensuelles du CA https://osmvideo.cloud68.co/user/fre-aux-yuh \n" +
|
"\t - les réunions mensuelles du CA https://osmvideo.cloud68.co/user/fre-aux-yuh \n" +
|
||||||
"\t - le nextcloud osm https://nextcloud.openstreetmap.fr\n" +
|
"\t - le nextcloud osm https://nextcloud.openstreetmap.fr\n" +
|
||||||
"\t - les status des services en ligne https://stats.uptimerobot.com/mQX5Vi5YW2";
|
"\t - les status des services en ligne https://stats.uptimerobot.com/mQX5Vi5YW2";
|
||||||
|
|
||||||
resteTopicMinutes: any = 10;
|
resteTopicMinutes: any = 10;
|
||||||
showDebug: boolean = false;
|
showDebug: boolean = false;
|
||||||
|
private startDate: Date = new Date();
|
||||||
|
private endDate: Date = new Date();
|
||||||
|
private topicChangeDate: Date = new Date();
|
||||||
|
|
||||||
|
|
||||||
|
updateTopicChangeDate(): void {
|
||||||
|
const currentTime = new Date();
|
||||||
|
const timeDifferenceInMilliseconds = this.topicChangeDate.getTime() - currentTime.getTime();
|
||||||
|
const timeDifferenceInSeconds = Math.abs(timeDifferenceInMilliseconds / 1000);
|
||||||
|
|
||||||
|
console.log(`Spent ${timeDifferenceInSeconds} seconds`);
|
||||||
|
this.subjects[this.currentSubjectId].spentSeconds += timeDifferenceInSeconds;
|
||||||
|
this.topicChangeDate = currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
parseTheListOfTopicsInPasteLand() {
|
parseTheListOfTopicsInPasteLand() {
|
||||||
|
|
||||||
let newTopics: any = []
|
let newTopics: any = []
|
||||||
let topics: any = this.pasteLand.split('*')
|
let topics: any = this.pasteLand.split('*')
|
||||||
topics.forEach((elem: string) => {
|
let accumulatedDuration: number = 0;
|
||||||
// console.log('topic', elem)
|
let ii = 0;
|
||||||
|
|
||||||
let boom = elem.split('-')
|
topics.forEach((topic: string) => {
|
||||||
|
let boom = topic.split('-')
|
||||||
if (boom[0]) {
|
if (boom[0]) {
|
||||||
|
accumulatedDuration += this.findMinutesDurationInDescription(topic) | 0
|
||||||
|
|
||||||
newTopics.push({
|
newTopics.push({
|
||||||
|
id: ii,
|
||||||
title: boom[0],
|
title: boom[0],
|
||||||
duration: 15,
|
duration: 15,
|
||||||
author: ''
|
author: '',
|
||||||
|
startDate: this.getStartDateAfterDuration(accumulatedDuration + ''),
|
||||||
|
endDate: this.getEndDateAfterDuration(accumulatedDuration + ''),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
ii += 1;
|
||||||
})
|
})
|
||||||
|
|
||||||
this.subjects = newTopics
|
this.subjects = newTopics
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Date object set to the specified time in the current time zone.
|
||||||
|
*
|
||||||
|
* @param {string} hour - A string representation of the hour, in 24-hour format.
|
||||||
|
* @param {string} [minute='00'] - A string representation of the minute (00-59).
|
||||||
|
* @returns {Date} A new Date object set to the specified time.
|
||||||
|
*/
|
||||||
|
makeDateFromHourToday(hourInput: string, minuteInput: string = '00') {
|
||||||
|
let [hour, minute] = hourInput.split(":");
|
||||||
|
let date = new Date();
|
||||||
|
date.setHours(parseInt(hour));
|
||||||
|
date.setMinutes(minuteInput ? parseInt(minuteInput) : parseInt(minute));
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the remaining time for a given topic, based on the current time and the start and end times of the topic.
|
||||||
|
*
|
||||||
|
* @param {Topic} topic - The topic for which to compute the remaining time.
|
||||||
|
*/
|
||||||
|
computeResteTopicMinutes(topic: Topic): void {
|
||||||
|
let currentSubjectDuration = topic.duration; // The duration of the current subject, in minutes
|
||||||
|
let currentSubjectStartTime = new Date(this.startTime); // The start time of the current subject
|
||||||
|
let currentSubjectEndTime = new Date(currentSubjectStartTime.getTime() + currentSubjectDuration * 60000); // The end time of the current subject
|
||||||
|
|
||||||
|
let remainingTime = currentSubjectEndTime.getTime() - new Date().getTime(); // The remaining time, in milliseconds
|
||||||
|
this.resteTopicMinutes = Math.floor(remainingTime / 60000); // The remaining time, in minutes
|
||||||
|
}
|
||||||
|
|
||||||
|
interval: any;
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.parseTheListOfTopicsInPasteLand()
|
this.parseTheListOfTopicsInPasteLand()
|
||||||
|
|
||||||
|
this.startDate = this.makeDateFromHourToday(this.startTime + '');
|
||||||
|
this.endDate = this.makeDateFromHourToday(this.endTime + '');
|
||||||
|
|
||||||
|
// this.interval = setInterval(() => {
|
||||||
|
this.updateProgressEveryPeriod();
|
||||||
|
// }, 1 * 1000);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
clearInterval(this.interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
nextSubject() {
|
nextSubject() {
|
||||||
|
this.updateTopicChangeDate()
|
||||||
this.currentSubjectId++
|
this.currentSubjectId++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
findMinutesDurationInDescription(topic: string): number {
|
||||||
|
let durationRegex = /-\s(\d+)min/g;
|
||||||
|
let matches = durationRegex.exec(topic);
|
||||||
|
if (matches) {
|
||||||
|
return parseInt(matches[1]);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getEndDateAfterDuration(accumulatedDuration: string) {
|
||||||
|
return this.makeDateFromHourToday(accumulatedDuration)
|
||||||
|
}
|
||||||
|
|
||||||
|
private getStartDateAfterDuration(accumulatedDuration: string) {
|
||||||
|
return this.makeDateFromHourToday(accumulatedDuration)
|
||||||
|
}
|
||||||
|
|
||||||
|
isTopicRunning(topic: Topic) {
|
||||||
|
let now = new Date();
|
||||||
|
return now >= topic.startDate && now <= topic.endDate && !topic.finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
countRemainingMinutes(topic: Topic) {
|
||||||
|
let now = new Date();
|
||||||
|
return Math.floor((topic.endDate.getTime() - now.getTime()) / 60000);
|
||||||
|
}
|
||||||
|
|
||||||
|
getPercentProgressTimeForTopic(topic: Topic) {
|
||||||
|
let now = new Date();
|
||||||
|
return Math.floor((now.getTime() - topic.startDate.getTime()) / (topic.endDate.getTime() - topic.startDate.getTime()) * 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
finishTopic(currentSubjectId: number) {
|
||||||
|
this.subjects[currentSubjectId].finished = true
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* only had one second to the current topic
|
||||||
|
*/
|
||||||
|
updateProgressEveryPeriod() {
|
||||||
|
this.subjects[this.currentSubjectId].spentSeconds += 1;
|
||||||
|
console.log('ajout au topic', this.currentSubjectId)
|
||||||
|
}
|
||||||
|
|
||||||
|
convertTextToHTMLLinks(text: string): string {
|
||||||
|
let urlRegex = /(https?:\/\/[^\s<]+[^<.,:;\"\'\]\s])(?!["\])\s])/g;
|
||||||
|
let matches = urlRegex.exec(text);
|
||||||
|
while (matches) {
|
||||||
|
let url = matches[1];
|
||||||
|
let linkText = url;
|
||||||
|
if (url.length > 30) {
|
||||||
|
linkText = url.substring(0, 30) + "...";
|
||||||
|
}
|
||||||
|
text = text.replace(url, `<a href="${url}">${linkText}</a>`);
|
||||||
|
matches = urlRegex.exec(text);
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
previousSubject() {
|
||||||
|
this.updateTopicChangeDate()
|
||||||
|
this.currentSubjectId < 1 ? this.currentSubjectId = 0 : this.currentSubjectId -= 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue