From 7239dfa0fab876fe1fc7b3d2c81b3cb86e41d6c7 Mon Sep 17 00:00:00 2001 From: Nicolas Constant Date: Wed, 21 Mar 2018 00:21:15 -0400 Subject: [PATCH] first iteration (and very candid) toots retrieval --- Mamoth/Mamoth.njsproj | 1 + Mamoth/src/app/app.module.ts | 9 ++- .../left-side-bar/left-side-bar.component.ts | 19 +++-- .../app/components/stream/stream.component.ts | 45 ++++++++---- .../app/components/toot/toot.component.html | 3 +- Mamoth/src/app/models/account.models.ts | 6 ++ Mamoth/src/app/models/stream.models.ts | 69 ++++++++++++++++++- .../streams-main-display.component.html | 2 +- .../streams-main-display.component.ts | 30 +++++--- Mamoth/src/app/services/accounts.service.ts | 15 ++-- .../services/models/mastodon.interfaces.ts | 2 +- Mamoth/src/app/services/streams.service.ts | 50 ++++++++++++++ 12 files changed, 204 insertions(+), 47 deletions(-) create mode 100644 Mamoth/src/app/services/streams.service.ts diff --git a/Mamoth/Mamoth.njsproj b/Mamoth/Mamoth.njsproj index 6468a2b8..bc3fc611 100644 --- a/Mamoth/Mamoth.njsproj +++ b/Mamoth/Mamoth.njsproj @@ -111,6 +111,7 @@ + diff --git a/Mamoth/src/app/app.module.ts b/Mamoth/src/app/app.module.ts index 85dd8c26..a81f69ee 100644 --- a/Mamoth/src/app/app.module.ts +++ b/Mamoth/src/app/app.module.ts @@ -1,7 +1,7 @@ import { BrowserModule } from "@angular/platform-browser"; import { FormsModule } from "@angular/forms"; import { HttpModule } from "@angular/http"; -import { NgModule } from "@angular/core"; +import { NgModule, APP_INITIALIZER } from "@angular/core"; import { RouterModule, Routes } from "@angular/router"; import { NgxElectronModule } from "ngx-electron"; @@ -15,6 +15,7 @@ import { TootComponent } from "./components/toot/toot.component"; import { RegisterNewAccountComponent } from "./pages/register-new-account/register-new-account.component"; import { AuthService } from "./services/auth.service"; import { AccountsService } from "./services/accounts.service"; +import { StreamsService } from "./services/streams.service"; const routes: Routes = [ { path: "", redirectTo: "home", pathMatch: "full" }, @@ -40,7 +41,11 @@ const routes: Routes = [ NgxElectronModule, RouterModule.forRoot(routes) ], - providers: [AuthService, AccountsService], + providers: [AuthService, AccountsService, StreamsService, { provide: APP_INITIALIZER, useFactory: settingsServiceFactory, deps: [AccountsService], multi: true }], bootstrap: [AppComponent] }) export class AppModule { } + +function settingsServiceFactory(service: AccountsService) { + return () => service.load(); +} diff --git a/Mamoth/src/app/components/left-side-bar/left-side-bar.component.ts b/Mamoth/src/app/components/left-side-bar/left-side-bar.component.ts index 999c85aa..247ea6af 100644 --- a/Mamoth/src/app/components/left-side-bar/left-side-bar.component.ts +++ b/Mamoth/src/app/components/left-side-bar/left-side-bar.component.ts @@ -18,17 +18,16 @@ export class LeftSideBarComponent implements OnInit, OnDestroy { private readonly accountsService: AccountsService) { } ngOnInit() { - this.accountsService.init.then(() => { - this.sub = this.accountsService.accountsSubject.subscribe((accounts: LocalAccount[]) => { - this.accounts.length = 0; + this.sub = this.accountsService.accountsSubject.subscribe((accounts: LocalAccount[]) => { + this.accounts.length = 0; - for (let acc of accounts) { - const acc1 = new AccountWrapper(); - acc1.username = acc.mastodonAccount.username; - acc1.avatar = acc.mastodonAccount.avatar; - this.accounts.push(acc1); - } - }); + for (let acc of accounts) { + const accWrapper = new AccountWrapper(); + console.warn(acc); + accWrapper.username = `${acc.mastodonAccount.username}@${acc.mastodonInstance.replace("https://", "")}`; + accWrapper.avatar = acc.mastodonAccount.avatar; + this.accounts.push(accWrapper); + } }); //const acc1 = new AccountWrapper(); diff --git a/Mamoth/src/app/components/stream/stream.component.ts b/Mamoth/src/app/components/stream/stream.component.ts index feccb4f1..1add0751 100644 --- a/Mamoth/src/app/components/stream/stream.component.ts +++ b/Mamoth/src/app/components/stream/stream.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from "@angular/core"; +import { Component, OnInit, Input } from "@angular/core"; import { Stream, TootWrapper } from "../../models/stream.models"; import { AccountWrapper } from "../../models/account.models"; @@ -8,27 +8,44 @@ import { AccountWrapper } from "../../models/account.models"; styleUrls: ["./stream.component.css"] }) export class StreamComponent implements OnInit { - stream: Stream; + private _stream: Stream; + + @Input() + set stream(stream: Stream) { + console.warn(stream); + + this._stream = stream; + this._stream.statuses.subscribe((toots: TootWrapper[]) => { + for (let t of toots) { + this.toots.push(t); + } + }); + } + + get stream(): Stream { + return this._stream; + } + toots: TootWrapper[] = []; constructor() { } ngOnInit() { //Stubs - const newStream = new Stream(); - newStream.streamName = "Stream Name"; - this.stream = newStream; + //const newStream = new Stream(); + //newStream.streamName = "Stream Name"; + //this.stream = newStream; - const acc1 = new AccountWrapper(); - acc1.username = "@mastodon.social@Gargron"; - acc1.avatar = "https://files.mastodon.social/accounts/avatars/000/000/001/original/4df197532c6b768c.png"; + //const acc1 = new AccountWrapper(); + //acc1.username = "@mastodon.social@Gargron"; + //acc1.avatar = "https://files.mastodon.social/accounts/avatars/000/000/001/original/4df197532c6b768c.png"; - for (let i = 0; i < 20; i++) { - const newToot = new TootWrapper(); - newToot.account = acc1; - newToot.content = "Lorem Elsass ipsum tristique semper elit jetz gehts los lacus habitant Hans sagittis baeckeoffe condimentum id, salu bredele ch'ai libero, ftomi! hop Pfourtz ! id munster auctor, Miss Dahlias rhoncus Yo dû. Salu bissame turpis ante amet non sed gal Spätzle Gal !"; - this.toots.push(newToot); - } + //for (let i = 0; i < 20; i++) { + // const newToot = new TootWrapper(); + // newToot.account = acc1; + // newToot.content = "Lorem Elsass ipsum tristique semper elit jetz gehts los lacus habitant Hans sagittis baeckeoffe condimentum id, salu bredele ch'ai libero, ftomi! hop Pfourtz ! id munster auctor, Miss Dahlias rhoncus Yo dû. Salu bissame turpis ante amet non sed gal Spätzle Gal !"; + // this.toots.push(newToot); + //} } goToTop(): boolean { diff --git a/Mamoth/src/app/components/toot/toot.component.html b/Mamoth/src/app/components/toot/toot.component.html index d3fbcd0e..eddb9162 100644 --- a/Mamoth/src/app/components/toot/toot.component.html +++ b/Mamoth/src/app/components/toot/toot.component.html @@ -2,7 +2,6 @@
-
-

{{ toot.content }}

+
diff --git a/Mamoth/src/app/models/account.models.ts b/Mamoth/src/app/models/account.models.ts index 95666428..52f40aca 100644 --- a/Mamoth/src/app/models/account.models.ts +++ b/Mamoth/src/app/models/account.models.ts @@ -1,4 +1,10 @@ +import { Account } from "../services/models/mastodon.interfaces"; + + export class AccountWrapper { + constructor() { + } + id: number; username: string; display_name: string; diff --git a/Mamoth/src/app/models/stream.models.ts b/Mamoth/src/app/models/stream.models.ts index efa94921..87d46c97 100644 --- a/Mamoth/src/app/models/stream.models.ts +++ b/Mamoth/src/app/models/stream.models.ts @@ -1,10 +1,75 @@ +import { Http, Headers, Response } from "@angular/http"; +import { BehaviorSubject } from "rxjs"; + import { AccountWrapper } from "./account.models"; +import { LocalAccount } from "../services/accounts.service"; +import { ApiRoutes } from "../services/models/api.settings"; +import { Account, Status } from "../services/models/mastodon.interfaces"; export class Stream { - streamName: string; + private apiRoutes = new ApiRoutes(); + + statuses = new BehaviorSubject([]); + + constructor( + private readonly httpService: Http, + public streamName: string, + private readonly type: StreamTypeEnum, + private readonly account: LocalAccount) { + + this.retrieveToots(); //TODO change this for WebSockets + } + + private retrieveToots(): void { + const route = this.getTimelineRoute(); + + const header = new Headers(); + header.append("Authorization", `Bearer ${this.account.tokenData.access_token}`); + + this.httpService.get(this.account.mastodonInstance + route, { headers: header }).toPromise() + .then((res: Response) => { + const statuses = (res.json() as Status[]) + .map((status: Status) => { + return new TootWrapper(status); + }); + + this.statuses.next(statuses); + }); + + } + + private getTimelineRoute(): string { + switch (this.type) { + case StreamTypeEnum.Home: + return this.apiRoutes.getHomeTimeline; + case StreamTypeEnum.Local: + return this.apiRoutes.getPublicTimeline + `?Local=true`; + case StreamTypeEnum.Public: + return this.apiRoutes.getPublicTimeline + `?Local=false`; + } + } + } +export enum StreamTypeEnum { + Home, + Public, + Local +} + + export class TootWrapper { - account: AccountWrapper; + constructor(status: Status) { + console.warn(status); + + this.account = new AccountWrapper(); + this.account.username = status.account.username; + this.account.display_name = status.account.display_name; + this.account.avatar = status.account.avatar; + + this.content = status.content; + } + + account: AccountWrapper; //TODO change to Account content: string; } diff --git a/Mamoth/src/app/pages/streams-main-display/streams-main-display.component.html b/Mamoth/src/app/pages/streams-main-display/streams-main-display.component.html index 81df9202..1aa8c29a 100644 --- a/Mamoth/src/app/pages/streams-main-display/streams-main-display.component.html +++ b/Mamoth/src/app/pages/streams-main-display/streams-main-display.component.html @@ -1,6 +1,6 @@
- +
diff --git a/Mamoth/src/app/pages/streams-main-display/streams-main-display.component.ts b/Mamoth/src/app/pages/streams-main-display/streams-main-display.component.ts index e38db180..cb6b7555 100644 --- a/Mamoth/src/app/pages/streams-main-display/streams-main-display.component.ts +++ b/Mamoth/src/app/pages/streams-main-display/streams-main-display.component.ts @@ -1,20 +1,32 @@ -import { Component, OnInit } from '@angular/core'; -import { Stream } from 'stream'; +import { Component, OnInit } from "@angular/core"; + +import { Stream } from "../../models/stream.models"; +import { StreamsService } from "../../services/streams.service"; + @Component({ - selector: 'app-streams-main-display', - templateUrl: './streams-main-display.component.html', - styleUrls: ['./streams-main-display.component.css'] + selector: "app-streams-main-display", + templateUrl: "./streams-main-display.component.html", + styleUrls: ["./streams-main-display.component.css"] }) export class StreamsMainDisplayComponent implements OnInit { streams: Stream[] = []; - constructor() { } + constructor(private readonly streamService: StreamsService) { + + + } ngOnInit() { - for (let i = 0; i < 3; i++) { - this.streams.push(new Stream()); - } + this.streamService.streamsSubject.subscribe((streams: Stream[]) => { + for (let s of streams) { + this.streams.push(s); + } + }); + + //for (let i = 0; i < 3; i++) { + // this.streams.push(new Stream()); + //} } } diff --git a/Mamoth/src/app/services/accounts.service.ts b/Mamoth/src/app/services/accounts.service.ts index e3651df0..271a7ab2 100644 --- a/Mamoth/src/app/services/accounts.service.ts +++ b/Mamoth/src/app/services/accounts.service.ts @@ -10,13 +10,16 @@ export class AccountsService { private localAccountKey = "localAccounts"; private apiRoutes = new ApiRoutes(); - accountsSubject: Subject; - init: Promise; //TODO load this service before any UI action + accountsSubject: BehaviorSubject; - constructor(private readonly httpService: Http) { - this.init = this.getAllLocalAccount().then((accounts) => { - this.accountsSubject = new BehaviorSubject(accounts); - }); + constructor(private readonly httpService: Http) {} + + load(): Promise { + return this.getAllLocalAccount() + .then((accounts) => { + this.accountsSubject = new BehaviorSubject(accounts); + return true; + }); } addNewAccount(mastodonInstance: string, email: string, token: TokenData) { diff --git a/Mamoth/src/app/services/models/mastodon.interfaces.ts b/Mamoth/src/app/services/models/mastodon.interfaces.ts index 71a735b0..608829b2 100644 --- a/Mamoth/src/app/services/models/mastodon.interfaces.ts +++ b/Mamoth/src/app/services/models/mastodon.interfaces.ts @@ -99,7 +99,7 @@ export interface Status { id: string; uri: string; url: string; - account: string; + account: Account; in_reply_to_id: string; in_reply_to_account_id: string; reblog: string; diff --git a/Mamoth/src/app/services/streams.service.ts b/Mamoth/src/app/services/streams.service.ts new file mode 100644 index 00000000..ca1f2d31 --- /dev/null +++ b/Mamoth/src/app/services/streams.service.ts @@ -0,0 +1,50 @@ +import { Injectable } from "@angular/core"; +import { Http } from "@angular/http"; +import { BehaviorSubject } from "rxjs"; + +import { Stream, StreamTypeEnum } from "../models/stream.models"; +import { AccountsService, LocalAccount } from "./accounts.service"; + +@Injectable() +export class StreamsService { + streamsSubject = new BehaviorSubject([]); + + constructor( + private readonly httpService: Http, + private readonly accountsService: AccountsService) { + + // Return home/local/public of all accounts + this.accountsService.accountsSubject + .subscribe((accounts: LocalAccount[]) => { + const streams: Stream[] = []; + for (let acc of accounts) { + const homeStream = new Stream(this.httpService, "Home", StreamTypeEnum.Home, acc); + const localStream = new Stream(this.httpService, "Local", StreamTypeEnum.Local, acc); + const publicStream = new Stream(this.httpService, "Public", StreamTypeEnum.Public, acc); + + streams.push(homeStream); + streams.push(localStream); + streams.push(publicStream); + } + this.streamsSubject.next(streams); + }); + } + + + //getStreams(): void { + // // Return home/local/public of all accounts + // this.accountsService.accountsSubject + // .map((accounts: LocalAccount[]) => { + // const streams: Stream[] = []; + // for (let acc of accounts) { + // const homeStream = new Stream(this.httpService, "Home", StreamTypeEnum.Home, acc); + // const localStream = new Stream(this.httpService, "Local", StreamTypeEnum.Local, acc); + // const publicStream = new Stream(this.httpService, "Public", StreamTypeEnum.Public, acc); + + // streams.push(homeStream); + // streams.push(localStream); + // streams.push(publicStream); + // } + // this.streamsSubject.next(streams); + // }); +}