Commit 34e68350 authored by Zéfling's avatar Zéfling 🎨
Browse files

Add messages reader

parent 76f51dad
......@@ -10,6 +10,10 @@
<a routerLink="/moments"
routerLinkActive="active-link">Moments</a>
</li>
<li>
<a routerLink="/messages"
routerLinkActive="active-link">Messages</a>
</li>
</ul>
<div *ngIf="multi">
<select (change)="change($event)">
......
......@@ -12,6 +12,7 @@ import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { TweetsCalendarComponent } from './tweets/tweets-calendar.component';
import { MomentsListComponent } from './moments/moments-list.component';
import { MessagesListComponent } from './messages/messages-list.component';
// pipe
import { NgForObjectPipe } from './pipes/ngfor-object';
import { MouthPipe } from './pipes/mouth';
......@@ -38,6 +39,10 @@ const appRoutes: Routes = [
path: 'tweets/:moment',
component: TweetsCalendarComponent
},
{
path: 'messages',
component: MessagesListComponent
},
{
path: '**',
redirectTo: 'tweets'
......@@ -50,6 +55,7 @@ const appRoutes: Routes = [
AppComponent,
TweetsCalendarComponent,
MomentsListComponent,
MessagesListComponent,
// pipes
NgForObjectPipe,
......
<div *ngIf="messages"
class="messages-total">
<span>
Total : {{messages.total | numFormat}} conversation{{messages.total > 0 ? 's' : ''}}
</span>
</div>
<nav *ngIf="messages"
class="messages-list">
<ul>
<li *ngFor="let conversation of (messages.conversation)"
(click)="selectConversation(conversation)">
<time class="thread-date">{{conversation.created_date | date:'yyyy-MM-dd HH:mm:ss'}}</time>
<span class="thread-total">{{(conversation.dmConversation?.messages?.length || 0) | numFormat}}
message{{(conversation.dmConversation?.messages?.length || 0) > 0 ? 's' : ''}}</span>
</li>
</ul>
</nav>
<div *ngIf="conversation"
class="conversation-title">
<div>
<span>{{conversation.created_date | date:'yyyy-MM-dd HH:mm:ss'}}</span>
</div>
<div>
<time class="tweet-date">{{conversation.created_date | date:'yyyy-MM-dd HH:mm:ss'}}</time> -
<span>{{(conversation.dmConversation?.messages?.length || 0) | numFormat}}
message{{(conversation.dmConversation?.messages?.length || 0) > 0 ? 's' : ''}}</span>
</div>
</div>
<div *ngIf="conversation"
class="conversation">
<ul>
<li class="message"
[class.message-me]="message.messageCreate?.me"
*ngFor="let message of conversation.dmConversation?.messages">
<div>
{{message.messageCreate?.createdAt | date:'yyyy-MM-dd HH:mm:ss'}}
</div>
<div class="message-text"
[innerHTML]="message.messageCreate?.html_text">
</div>
</li>
</ul>
</div>
\ No newline at end of file
:host {
display:grid;
grid-template: [header-left] "a c" auto [header-right]
[main-left] "b e" auto [main-right]
[main-left] "b d" 1fr [main-right]
[footer-left] "b d" 30px [footer-right] / 250px 1fr;
max-width: 100%;
}
.messages-total {
grid-area: a;
}
.messages-list {
grid-area: b;
ul {
list-style: none;
padding: 0;
margin: 0;
}
li {
background-color: var(--item-bd-color);
cursor: pointer;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
margin-bottom: 3px;
& > :first-child {
width: 100%;
font-weight: 700;
}
&:hover {
transition: background-color .4s;
background-color: var(--item-bd-hover-color);
}
time,
.tweet-total {
font-size: 80%;
}
}
}
.conversation-title {
grid-area: c;
}
.conversation {
grid-area: d;
ul {
list-style: none;
padding: 0;
margin: 0;
}
}
.message {
display: block;
background-color: var(--panel-bg-color);
box-shadow: var(--panel-shadow);
margin: 5px 5px 12px 5px;
&:not(.message-me) {
margin-right: 30%;
}
&.message-me{
margin-left: 30%;
}
}
.message-text {
padding: 5px;
white-space: pre-wrap;
word-break: break-word;
}
\ No newline at end of file
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
import { Lightbox } from 'ngx-lightbox';
import { Messages, Thread, Conversation } from './messages';
import { UserService, TypeData } from '../user/user.service';
import { AppService } from '../app.service';
import { MessagesService } from './messages.service';
@Component({
selector: 'messages-list',
templateUrl: './messages-list.component.html',
styleUrls: ['./messages-list.component.scss']
})
export class MessagesListComponent implements OnInit, OnDestroy {
messages: Messages;
thread: Thread;
listener: Subscription[] = [];
conversation: Conversation;
private album: { src: string, caption: string, thumb: string }[] = [];
constructor(
private userService: UserService,
private messagesService: MessagesService,
private lightbox: Lightbox,
private appService: AppService
) {
this.listener.push(
this.messagesService.onDataLoaded.subscribe((messages: Messages) => {
console.warn(messages);
this.messages = messages;
// select current
}),
this.appService.updateData.subscribe(() => {
this.ngOnInit();
})
);
}
ngOnInit() {
this.userService.loadData(TypeData.MESSAGES);
}
ngOnDestroy() {
this.listener.forEach(s => s.unsubscribe());
}
selectConversation(conversation: Conversation) {
console.log('conversation', conversation);
this.conversation = conversation;
}
}
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Subject } from 'rxjs';
import { Messages, Message } from './messages';
import { UserService, TypeData } from '../user/user.service';
import { AppService } from '../app.service';
import { pattern } from '../common/utils';
@Injectable({
providedIn: 'root',
})
export class MessagesService {
readonly onData = new Subject<void>();
readonly onDataLoaded = new Subject<Messages>();
readonly messages = new Messages();
constructor(
private http: HttpClient,
private userService: UserService,
private appService: AppService
) {
this.userService.onDataLoaded.subscribe(this.loadData.bind(this));
this.onData.subscribe(this.readData.bind(this));
}
/**
* read data
*/
private loadData(typeData: TypeData) {
if (typeData === TypeData.MESSAGES) {
if (!this.messages.init) {
this.http
.get(this.appService.getPath() + 'direct-message.js', { responseType: 'text' })
.subscribe(
(data: string) => {
try {
this.messages.conversation = JSON.parse(data.replace(pattern.win, ''));
this.messages.init = true;
this.onData.next();
} catch (e) {
this.messages.error = true;
this.messages.errorMessage = 'data not readable';
}
},
() => {
this.messages.error = true;
this.messages.errorMessage = 'file not exit';
});
} else {
this.onDataLoaded.next(this.messages);
}
}
}
/**
* read and format data
*/
private readData() {
const data = this.messages;
console.log(data);
data.total = this.messages.conversation.length || 0;
for (const i in data.conversation) {
if (data.conversation[i]) {
const conversation = data.conversation[i];
conversation.created_date = new Date(data.conversation[i].dmConversation.messages[0].messageCreate.createdAt);
for (const messages of conversation.dmConversation.messages) {
this.formatTweet(messages.messageCreate);
}
}
}
this.onDataLoaded.next(this.messages);
}
formatTweet(message: Message) {
if (message) {
let html_text = message.text;
html_text = html_text.replace(/(http:\/\/[^\s"])/g, `<a href="$1">$1</a>`);
message.html_text = html_text;
console.log(message.recipientId, message.senderId, this.userService.accountData.accountId);
message.me = message.recipientId === this.userService.accountData.accountId;
}
}
}
export class Message {
recipientId: string;
text: string;
mediaUrls: string[];
senderId: string;
id: string;
createdAt: string;
// extra
html_text: string;
me: boolean;
}
export class Thread {
messageCreate: Message;
}
export class ConversationInformation {
conversationId: string;
messages: Thread[];
}
export class Conversation {
dmConversation: ConversationInformation;
// extra
created_date: Date;
}
export class Messages {
conversation: Conversation[] = [];
minDate: Date;
maxDate: Date;
total = 0;
error = false;
errorMessage = '';
init = false;
}
......@@ -10,7 +10,6 @@
max-width: 100%;
}
.moments-total {
grid-area: a;
display: flex;
......@@ -84,7 +83,6 @@
flex: 1;
}
.tweet {
display: block;
background-color: var(--panel-bg-color);
......@@ -95,7 +93,7 @@
.tweet-text {
padding: 5px;
white-space: pre-wrap;
word-break: break-all;
word-break: break-word;
}
.tweet-media {
......@@ -117,5 +115,4 @@
box-shadow: 2px 2px 4px rgba(0,0,0, .9);
}
}
}
\ No newline at end of file
}
......@@ -54,9 +54,7 @@ export class MomentsListComponent implements OnInit, OnDestroy {
}
ngOnDestroy() {
for (const l of this.listener) {
l.unsubscribe();
}
this.listener.forEach(s => s.unsubscribe());
}
selectMoment(moment: Moment) {
......
......@@ -123,7 +123,7 @@
.tweet-text {
padding: 5px;
white-space: pre-wrap;
word-break: break-all;
word-break: break-word;
}
.tweet-infos {
......@@ -137,7 +137,6 @@
}
}
.tweet-media {
display: flex;
align-content: center;
......
......@@ -8,7 +8,8 @@ import { AppService } from '../app.service';
export enum TypeData {
TWEETS = 'tweets',
MOMENTS = 'moments'
MOMENTS = 'moments',
MESSAGES = 'messages'
}
@Injectable({
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment