[A] channel.service functionality, create channel from sidebar

This commit is contained in:
Jan 2020-10-31 00:07:55 +01:00
parent 42640f113c
commit 1da9c1e81a
5 changed files with 194 additions and 8 deletions

View file

@ -1,9 +1,160 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable, of, Subject } from 'rxjs';
import { Channel } from './channel';
import { SupaService } from './supa.service';
@Injectable({
providedIn: 'root'
})
export class ChannelService {
channelMap = {};
channels: BehaviorSubject<any> = new BehaviorSubject([]);
isListening: boolean = false;
constructor() { }
constructor(
private supa: SupaService,
) { }
/**
* Get Channels from local store.
* Requests data if store is emtpy.
* @returns Observable<Channel[]>
*/
getChannels(): Observable<Channel[]> {
if (Object.values(this.channelMap).length === 0) {
console.log('getChannels - REFRESH')
return this.refreshChannels();
} else {
console.log('getChannels - LOCAL')
return this.channels.asObservable();
}
}
/**
* Listen to realtime events from channel db.
*/
subscribeToChannels() {
if (!this.isListening) {
this.isListening = true;
this.supa.client.from<Channel>('channel').on('*', payload => {
console.log('subscribeToChannels - REALTIME EVENT', payload);
if ((payload.eventType === 'INSERT') || (payload.eventType === 'UPDATE')) {
this.channelMap[payload.new.id] = payload.new;
} else {
delete this.channelMap[payload.old.id];
}
this.next();
}).subscribe();
}
}
/**
* Requests up to date data from API.
* Returns the local copy.
* @returns Observable<Channel>
*/
refreshChannels(): Observable<Channel[]> {
this.subscribeToChannels();
this.supa.client.from<Channel>('channel').select()
.then(channels => this.updateStore(channels.body))
.catch(error => console.log('Error: ', error));
return this.channels.asObservable();
}
/**
* Update the local store with provided channels
* @param channels
*/
updateStore(channels: Channel[]) {
channels.forEach(e => {
this.channelMap[e.id] = e;
});
this.next();
}
/**
* Emits local store.
*/
next = () => this.channels.next(Object.values(this.channelMap));
/**
* Retrieve channel from local store.
* @param id
*/
getOne(id: number) {
if (this.channelMap[id]) {
return of(this.channelMap[id]);
} else {
const subject: Subject<Channel> = new Subject();
this.supa.client.from<Channel>('channel').select('id, name, description')
.filter(<never>'id', 'eq', id)
.then(data => {
this.updateStore([data.body[0]]);
subject.next(data.body[0]);
subject.complete();
})
.catch(error => {
subject.error(error);
subject.complete();
});
return subject.asObservable();
}
}
/**
*
* @param channel
*/
updateOne(channel: Channel): Observable<Channel> {
const subject: Subject<Channel> = new Subject();
this.supa.client.from<Channel>('channel').update(channel)
.match({ id: channel.id })
.then(data => {
subject.next(data.body[0]);
subject.complete();
})
.catch(error => {
subject.error(error);
subject.complete();
});
return subject.asObservable();
}
/**
* Removes one channel from db.
* @param channel
*/
deleteOne(channel: Channel): Observable<Channel> {
const subject: Subject<Channel> = new Subject();
this.supa.client.from<Channel>('channel').delete()
.match({ id: channel.id })
.then(data => {
subject.next(channel);
subject.complete();
})
.catch(error => {
subject.error(error);
subject.complete();
});
return subject.asObservable();
}
/**
* Creates a channel on the db.
* @param channel
*/
addOne(channel: Channel): Observable<Channel> {
const subject: Subject<Channel> = new Subject();
this.supa.client.from<Channel>('channel').insert(channel)
.then(data => {
subject.next(data.body[0]);
subject.complete();
})
.catch(error => {
subject.error(error);
subject.complete();
});
return subject.asObservable();
}
}

View file

@ -0,0 +1,13 @@
export class Channel {
id: number;
name: string;
description: string;
inserted_at: string | Date;
created_by: string;
constructor(created_by: string, name: string, description?: string) {
this.name = name;
this.description = description;
this.created_by = created_by;
}
}

View file

@ -7,7 +7,6 @@ import { SupaService } from './supa.service';
providedIn: 'root'
})
export class StandupService {
// standupMap: Map<number, StandUp> = new Map();
standupMap = {};
standups: BehaviorSubject<any> = new BehaviorSubject([]);
isListening: boolean = false;
@ -68,7 +67,6 @@ export class StandupService {
*/
updateStore(standups: StandUp[]) {
standups.forEach(e => {
// this.standupMap.set(e.id, e);
this.standupMap[e.id] = e;
});
this.next();

View file

@ -2,13 +2,12 @@
<p><strong>Standup</strong> <strong class="newBtn" (click)="createStandUp()">+</strong></p>
<ul class="list-unstyled">
<li *ngFor="let s of standups" [title]="s.description" [routerLink]="'/huddle/'+s.id">{{s.name}}</li>
<li *ngIf="standups && (standups.length === 0)"><small>There are no standups yet.</small></li>
</ul>
<p><strong>Channel</strong> <strong class="newBtn">+</strong></p>
<p><strong>Channel</strong> <strong class="newBtn" (click)="createChannel()">+</strong></p>
<ul class="list-unstyled">
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
<li *ngFor="let c of channels" [title]="c.description" [routerLink]="'/channel/'+c.id">{{c.name}}</li>
<li *ngIf="channels && (channels.length === 0)"><small>There are no channels yet.</small></li>
</ul>
<p><strong>Settings</strong></p>
<ul class="list-unstyled">

View file

@ -3,6 +3,10 @@ import { Observable, throwError } from 'rxjs';
import { StandUp } from '../api/supabase/standup';
import { StandupService } from '../api/supabase/standup.service';
import { environment } from '../../environments/environment';
import { Channel } from '../api/supabase/channel';
import { ChannelService } from '../api/supabase/channel.service';
import { SupaService } from '../api/supabase/supa.service';
import { User } from '../api/supabase/user';
@Component({
selector: 'app-sidebar',
@ -11,10 +15,13 @@ import { environment } from '../../environments/environment';
})
export class SidebarComponent implements OnInit {
standups: StandUp[] = [];
channels: Channel[] = [];
environment = environment;
constructor(
private supaService: SupaService,
private standupSevice: StandupService,
private channelService: ChannelService,
) { }
ngOnInit() {
@ -22,12 +29,20 @@ export class SidebarComponent implements OnInit {
console.log('ChannelListComponent - StandUps', standups);
this.standups = standups;
});
this.loadChannels().subscribe(channels => {
console.log('ChannelListComponent - Channels', channels);
this.channels = channels;
});
}
loadStandUps(): Observable<StandUp[]> {
return this.standupSevice.getStandUps();
}
loadChannels(): Observable<Channel[]> {
return this.channelService.getChannels();
}
createStandUp() {
this.standupSevice.addOne(new StandUp('test', 'test')).subscribe(
data => console.log(data),
@ -35,4 +50,14 @@ export class SidebarComponent implements OnInit {
)
}
createChannel() {
if (!this.supaService.userProfile.id) {
return;
}
this.channelService.addOne(new Channel(this.supaService.userProfile.id, 'test', 'test')).subscribe(
data => console.log(data),
error => console.error(error)
)
}
}