...
 
Commits (2)
......@@ -33,6 +33,7 @@
[class.has-v2-navbar]="featuresService.has('top-feeds')"
[class.is-pro-domain]="isProDomain"
>
<m-emailConfirmation></m-emailConfirmation>
<m-announcement [id]="'blockchain:sale'" *ngIf="false">
<span
class="m-blockchain--wallet-address-notice--action"
......
import { NgModule } from '@angular/core';
import { CommonModule as NgCommonModule } from '@angular/common';
import { RouterModule, Router } from '@angular/router';
import { RouterModule, Router, Routes } from '@angular/router';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MINDS_PIPES } from './pipes/pipes';
......@@ -126,9 +126,17 @@ import { ShadowboxSubmitButtonComponent } from './components/shadowbox-submit-bu
import { FormDescriptorComponent } from './components/form-descriptor/form-descriptor.component';
import { FormToastComponent } from './components/form-toast/form-toast.component';
import { SsoService } from './services/sso.service';
import { EmailConfirmationComponent } from './components/email-confirmation/email-confirmation.component';
PlotlyModule.plotlyjs = PlotlyJS;
const routes: Routes = [
{
path: 'email-confirmation',
redirectTo: '/',
},
];
@NgModule({
imports: [
NgCommonModule,
......@@ -137,6 +145,7 @@ PlotlyModule.plotlyjs = PlotlyJS;
FormsModule,
ReactiveFormsModule,
PlotlyModule,
RouterModule.forChild(routes),
],
declarations: [
MINDS_PIPES,
......@@ -241,6 +250,7 @@ PlotlyModule.plotlyjs = PlotlyJS;
FormDescriptorComponent,
FormToastComponent,
ShadowboxSubmitButtonComponent,
EmailConfirmationComponent,
],
exports: [
MINDS_PIPES,
......@@ -340,6 +350,7 @@ PlotlyModule.plotlyjs = PlotlyJS;
FormDescriptorComponent,
FormToastComponent,
ShadowboxSubmitButtonComponent,
EmailConfirmationComponent,
],
providers: [
SiteService,
......
......@@ -67,4 +67,9 @@ m-announcement {
}
}
}
.m-announcement__clickable {
cursor: pointer;
font-weight: bold;
}
}
......@@ -14,7 +14,7 @@ import { Client } from '../../../services/api';
<ng-content></ng-content>
</div>
<div class="m-announcement--close" (click)="close()">
<div class="m-announcement--close" *ngIf="canClose" (click)="close()">
<i class="material-icons">close</i>
</div>
</div>
......@@ -24,6 +24,8 @@ export class AnnouncementComponent {
minds: Minds = window.Minds;
hidden: boolean = false;
@Input() id: string = 'default';
@Input() canClose: boolean = true;
@Input() remember: boolean = true;
constructor(private storage: Storage) {}
......@@ -32,7 +34,10 @@ export class AnnouncementComponent {
}
close() {
this.storage.set('hide-announcement:' + this.id, true);
if (this.remember) {
this.storage.set('hide-announcement:' + this.id, true);
}
this.hidden = true;
}
}
<ng-container *ngIf="shouldShow">
<m-announcement
id="email-confirmation"
[canClose]="canClose"
[remember]="false"
>
Please confirm your email address.
<ng-container *ngIf="!sent"
>Didn't get it?
<span class="m-announcement__clickable" (click)="send()"
>Click here to send again.</span
></ng-container
>
</m-announcement>
</ng-container>
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
OnDestroy,
OnInit,
} from '@angular/core';
import { EmailConfirmationService } from './email-confirmation.service';
import { Session } from '../../../services/session';
import { Subscription } from 'rxjs';
/**
* Component that displays an announcement-like banner
* asking the user to confirm their email address and a link
* to re-send the confirmation email.
* @see AnnouncementComponent
*/
@Component({
providers: [EmailConfirmationService],
selector: 'm-emailConfirmation',
templateUrl: 'email-confirmation.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class EmailConfirmationComponent implements OnInit, OnDestroy {
sent: boolean = false;
shouldShow: boolean = false;
canClose: boolean = false;
protected userEmitter$: Subscription;
protected canCloseTimer: number;
protected minds = window.Minds;
constructor(
protected service: EmailConfirmationService,
protected session: Session,
protected cd: ChangeDetectorRef
) {}
ngOnInit(): void {
this.setShouldShow(this.session.getLoggedInUser());
this.userEmitter$ = this.session.userEmitter.subscribe(user => {
this.sent = false;
this.setShouldShow(user);
this.detectChanges();
});
this.canCloseTimer = window.setTimeout(() => {
this.canClose = true;
this.detectChanges();
}, 3000);
}
ngOnDestroy(): void {
window.clearTimeout(this.canCloseTimer);
if (this.userEmitter$) {
this.userEmitter$.unsubscribe();
}
}
/**
* Re-calculates the visibility of the banner
* @param {Object} user
*/
setShouldShow(user): void {
this.shouldShow =
!this.minds.from_email_confirmation &&
user &&
user.email_confirmed === false;
}
/**
* Uses the service to re-send the confirmation email
*/
async send(): Promise<void> {
this.sent = true;
this.detectChanges();
try {
const sent = await this.service.send();
if (!sent) {
this.sent = false;
}
} catch (e) {}
this.detectChanges();
}
detectChanges(): void {
this.cd.markForCheck();
this.cd.detectChanges();
}
}
import { Injectable } from '@angular/core';
import { Client } from '../../../services/api/client';
/**
* API implementation service for Email Confirmation component
* @see EmailConfirmationComponent
*/
@Injectable()
export class EmailConfirmationService {
constructor(protected client: Client) {}
/**
* Attempts to re-send the confirmation email to the current logged in user
*/
async send(): Promise<boolean> {
const response = (await this.client.post(
'api/v2/email/confirmation/resend',
{}
)) as any;
return Boolean(response && response.sent);
}
}
......@@ -37,9 +37,14 @@
id="email"
name="email"
[(ngModel)]="email"
(keyup)="change()"
(keyup)="change(); changeEmail()"
/>
</li>
<li class="m-settings--emails-campaigns__note" *ngIf="emailChanged" i18n>
Note: If you change your email address, it will need to be confirmed
again.
</li>
</ul>
</div>
......
......@@ -26,5 +26,15 @@ m-settings--emails {
margin-left: 8px;
}
}
.m-settings--emails-campaigns__note {
font-size: 0.8em;
line-height: 1;
padding: 2px 8px 0;
@include m-theme() {
color: themed($m-grey-300);
}
}
}
}
......@@ -4,6 +4,7 @@ import { Subscription } from 'rxjs';
import { OverlayModalService } from '../../../services/ux/overlay-modal';
import { ConfirmPasswordModalComponent } from '../../modals/confirm-password/modal.component';
import { Session } from '../../../services/session';
@Component({
selector: 'm-settings--emails',
......@@ -33,6 +34,7 @@ export class SettingsEmailsComponent implements OnInit {
error: string = '';
changed: boolean = false;
emailChanged: boolean = false;
saved: boolean = false;
inProgress: boolean = false;
loading: boolean = false;
......@@ -41,7 +43,8 @@ export class SettingsEmailsComponent implements OnInit {
constructor(
public client: Client,
public overlayModal: OverlayModalService
public overlayModal: OverlayModalService,
protected session: Session
) {}
ngOnInit() {
......@@ -77,6 +80,10 @@ export class SettingsEmailsComponent implements OnInit {
this.saved = false;
}
changeEmail() {
this.emailChanged = true;
}
canSubmit() {
return this.changed;
}
......@@ -89,7 +96,13 @@ export class SettingsEmailsComponent implements OnInit {
notifications: this.notifications,
})
.then((response: any) => {
if (this.emailChanged && window.Minds.user) {
window.Minds.user.email_confirmed = false;
this.session.inject(window.Minds.user);
}
this.changed = false;
this.emailChanged = false;
this.saved = true;
this.error = '';
......
......@@ -39,6 +39,7 @@ interface Minds {
};
};
contribution_values: { [key: string]: number };
from_email_confirmation?: boolean;
}
interface MindsNavigation {
......