...
 
Commits (8)
This diff is collapsed.
import { Component, EventEmitter } from '@angular/core';
import { Client } from '../../../services/api';
import { UserAvatarService } from '../../services/user-avatar.service';
import { of, Observable } from 'rxjs';
@Component({
selector: 'minds-avatar',
......@@ -14,17 +14,28 @@ import { Client } from '../../../services/api';
],
outputs: ['added'],
template: `
<div class="minds-avatar" [style.background-image]="'url(' + src + ')'">
<div
class="minds-avatar"
[ngStyle]="{ 'background-image': 'url(' + (getSrc() | async) + ')' }"
>
<img
*ngIf="!src"
*ngIf="!(userAvatarService.src$ | async)"
src="{{ minds.cdn_assets_url }}assets/avatars/blue/default-large.png"
class="mdl-shadow--4dp"
/>
<div *ngIf="editing" class="overlay">
<i class="material-icons">{{ icon }}</i>
<ng-container *ngIf="showPrompt">
<span *ngIf="src" i18n="@@COMMON__AVATAR__CHANGE">Change avatar</span>
<span *ngIf="!src" i18n="@@COMMON__AVATAR__ADD">Add an avatar</span>
<span
*ngIf="userAvatarService.src$ | async"
i18n="@@COMMON__AVATAR__CHANGE"
>Change avatar</span
>
<span
*ngIf="!(userAvatarService.src$ | async)"
i18n="@@COMMON__AVATAR__ADD"
>Add an avatar</span
>
</ng-container>
</div>
<input *ngIf="editing" type="file" #file (change)="add($event)" />
......@@ -40,18 +51,21 @@ export class MindsAvatar {
index: number = 0;
icon: string = 'camera';
showPrompt: boolean = true;
file: any;
added: EventEmitter<any> = new EventEmitter();
constructor(public userAvatarService: UserAvatarService) {}
set _object(value: any) {
if (!value) return;
value.icontime = value.icontime ? value.icontime : '';
this.object = value;
this.src = `${this.minds.cdn_url}fs/v1/avatars/${this.object.guid}/large/${this.object.icontime}`;
if (this.object.type === 'user')
if (this.object.type !== 'user') {
this.src = `${this.minds.cdn_url}fs/v1/avatars/${this.object.guid}/large/${this.object.icontime}`;
} else if (this.object.guid !== this.minds.user.guid) {
this.src = `${this.minds.cdn_url}icon/${this.object.guid}/large/${this.object.icontime}`;
}
}
set _src(value: any) {
......@@ -63,6 +77,10 @@ export class MindsAvatar {
if (!this.editing && this.file) this.done();
}
/**
* New avatar added.
* @param e - the element.
*/
add(e) {
if (!this.editing) return;
......@@ -78,6 +96,9 @@ export class MindsAvatar {
typeof reader.result === 'string'
? reader.result
: reader.result.toString();
if (this.object.type === 'user' && this.isOwnerAvatar()) {
this.userAvatarService.src$.next(this.src);
}
};
reader.readAsDataURL(this.file);
......@@ -87,9 +108,28 @@ export class MindsAvatar {
if (this.waitForDoneSignal !== true) this.done();
}
/**
* Called upon being done.
*/
done() {
console.log('sending done');
this.added.next(this.file);
this.file = null;
}
/**
* Gets the src of the image
* @returns { Observables<string> } the src for the image.
*/
getSrc(): Observable<string> {
return this.isOwnerAvatar() ? this.userAvatarService.src$ : of(this.src);
}
/**
* Determined whether this is a users avatar.
* @returns true if the object guid matches the currently logged in user guid
*/
isOwnerAvatar(): boolean {
return this.object.guid === this.minds.user.guid;
}
}
......@@ -22,7 +22,7 @@ export class NSFWSelectorComponent {
@Input('service') serviceRef: string = 'consumer';
@Input('consumer') consumer: false;
@Input('expanded') expanded: false;
@Output('selected') onSelected: EventEmitter<any> = new EventEmitter();
@Output('selectedChange') onSelected: EventEmitter<any> = new EventEmitter();
constructor(
public creatorService: NSFWSelectorCreatorService,
......@@ -33,7 +33,9 @@ export class NSFWSelectorComponent {
ngOnInit() {
if (this.service.reasons) {
this.service.reasons.map(r => this.toggle(r.value));
for (const reason of this.service.reasons) {
this.toggle(reason.value, false);
}
}
}
......@@ -64,14 +66,17 @@ export class NSFWSelectorComponent {
}
}
toggle(reason) {
toggle(reason, triggerChange = true) {
if (reason.locked) {
return;
}
this.service.toggle(reason);
const reasons = this.service.reasons.filter(r => r.selected);
this.onSelected.next(reasons);
if (triggerChange) {
const reasons = this.service.reasons.filter(r => r.selected);
this.onSelected.next(reasons);
}
}
hasSelections(): boolean {
......
......@@ -231,7 +231,7 @@
<m-nsfw-selector
service="editing"
[selected]="entity.nsfw"
(selected)="onNSFWSelected($event)"
(selectedChange)="onNSFWSelected($event)"
>
</m-nsfw-selector>
</li>
......
/**
* @author Ben Hayward
* @desc Singleton service used to store the current user avatar as a BehaviorSubject.
*/
import { Injectable } from '@angular/core';
import { BehaviorSubject, Subscription } from 'rxjs';
import { Session } from '../../services/session';
import { MindsUser } from '../../interfaces/entities';
@Injectable({
providedIn: 'root',
})
export class UserAvatarService {
private minds = window.Minds;
private user: MindsUser;
public src$: BehaviorSubject<string> = new BehaviorSubject<string>('');
public loggedIn$: Subscription;
constructor(public session: Session) {
this.init();
// Subscribe to loggedIn$ and on login, update src$.
if (this.session.loggedinEmitter) {
this.loggedIn$ = this.session.loggedinEmitter.subscribe(is => {
if (is) {
this.src$.next(this.getSrc());
}
});
}
}
/**
* Sets the current user and avatar src.
*/
public init(): void {
this.user = this.session.getLoggedInUser();
this.src$.next(this.getSrc());
}
/**
* Gets the Src string using the global minds object and the held user object.
*/
public getSrc(): string {
return `${this.minds.cdn_url}icon/${this.user.guid}/large/${this.user.icontime}`;
}
}
......@@ -3,6 +3,7 @@ import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { Client } from '../../../services/api';
import { Session } from '../../../services/session';
import { UserAvatarService } from '../../../common/services/user-avatar.service';
@Component({
moduleId: module.id,
......@@ -31,7 +32,8 @@ export class LoginForm {
public session: Session,
public client: Client,
fb: FormBuilder,
private zone: NgZone
private zone: NgZone,
private userAvatarService: UserAvatarService
) {
this.form = fb.group({
username: ['', Validators.required],
......@@ -65,6 +67,7 @@ export class LoginForm {
// TODO: [emi/sprint/bison] Find a way to reset controls. Old implementation throws Exception;
this.inProgress = false;
this.session.login(data.user);
this.userAvatarService.init();
this.done.next(data.user);
})
.catch(e => {
......@@ -102,6 +105,7 @@ export class LoginForm {
})
.then((data: any) => {
this.session.login(data.user);
this.userAvatarService.init();
this.done.next(data.user);
})
.catch(e => {
......
......@@ -134,7 +134,7 @@ import { Session } from '../../../services/session';
<m-nsfw-selector
service="editing"
[selected]="group.nsfw"
(selected)="onNSFWSelected($event)"
(selectedChange)="onNSFWSelected($event)"
>
</m-nsfw-selector>
</li>
......
......@@ -115,7 +115,7 @@ import { BlockListService } from '../../../../common/services/block-list.service
<m-nsfw-selector
service="editing"
[selected]="user.nsfw_lock"
(selected)="setNSFWLock($event)"
(selectedChange)="setNSFWLock($event)"
>
</m-nsfw-selector>
</li>
......
......@@ -171,7 +171,7 @@
service="editing"
[selected]="activity.nsfw"
[locked]="activity.ownerObj.nsfw_lock"
(selected)="onNSWFSelections($event)"
(selectedChange)="onNSWFSelections($event)"
>
</m-nsfw-selector>
</ng-container>
......
......@@ -392,7 +392,7 @@ m-media--grid {
}
}
> *:not(m-post-menu) {
> *:not(m-post-menu):not(m-wire-button) {
vertical-align: middle;
margin-left: 0.35em;
......@@ -483,8 +483,13 @@ m-media--grid {
}
}
.m-wire-button > .ion-icon {
transform: scale(1.2);
.m-wire-button {
padding: 3px 6px;
& > .ion-icon {
margin-right: 4px;
transform: scale(1.2);
}
}
.m-media-content--extra {
......
......@@ -2,7 +2,7 @@
<ng-container *mIfFeature="'top-feeds'">
<m-nsfw-selector
[consumer]="true"
(selected)="onNSFWSelected($event)"
(selectedChange)="onNSFWSelected($event)"
></m-nsfw-selector>
</ng-container>
<ng-container *ngIf="showBoostOptions">
......
......@@ -60,7 +60,7 @@
</label>
<ng-container *mIfFeature="'top-feeds'; else oldNSFW">
<m-nsfw-selector (selected)="onNSWFSelections($event)">
<m-nsfw-selector (selectedChange)="onNSWFSelections($event)">
</m-nsfw-selector>
</ng-container>
......
......@@ -6,7 +6,6 @@
*/
padding: 3px;
height: auto;
line-height: 18px;
cursor: pointer;
@include m-theme() {
color: themed($m-blue);
......@@ -21,6 +20,7 @@
> .ion-icon {
// transform: scale(1.6);
font-size: 18px;
vertical-align: middle;
}
span {
......