MOBILE-3833 notifications: Update styles
parent
6255c86708
commit
c64f0b9353
|
@ -17,20 +17,11 @@
|
||||||
</ion-refresher>
|
</ion-refresher>
|
||||||
<core-loading [hideUntil]="notificationsLoaded">
|
<core-loading [hideUntil]="notificationsLoaded">
|
||||||
|
|
||||||
<div class="ion-padding" *ngIf="canMarkAllNotificationsAsRead">
|
|
||||||
<ion-button [disabled]="loadingMarkAllNotificationsAsRead" expand="block" (click)="markAllNotificationsAsRead()" fill="outline">
|
|
||||||
<ion-icon slot="start" name="fas-check" aria-hidden="true" *ngIf="!loadingMarkAllNotificationsAsRead"></ion-icon>
|
|
||||||
<ion-spinner slot="start" [attr.aria-label]="'core.loading' | translate" *ngIf="loadingMarkAllNotificationsAsRead">
|
|
||||||
</ion-spinner>
|
|
||||||
{{ 'addon.notifications.markallread' | translate }}
|
|
||||||
</ion-button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ion-item *ngFor="let notification of notifications" class="ion-text-wrap" [attr.aria-label]="
|
<ion-item *ngFor="let notification of notifications" class="ion-text-wrap" [attr.aria-label]="
|
||||||
notification.timeread
|
notification.timeread
|
||||||
? notification.subject
|
? notification.subject
|
||||||
: 'addon.notifications.unreadnotification' | translate: {$a: notification.subject}"
|
: 'addon.notifications.unreadnotification' | translate: {$a: notification.subject}"
|
||||||
(click)="openNotification(notification)" button [detail]="true" lines="true">
|
(click)="openNotification(notification)" button [detail]="false" lines="full">
|
||||||
<core-user-avatar *ngIf="notification.useridfrom > 0" [user]="notification" slot="start"
|
<core-user-avatar *ngIf="notification.useridfrom > 0" [user]="notification" slot="start"
|
||||||
[profileUrl]="notification.profileimageurlfrom" [fullname]="notification.userfromfullname"
|
[profileUrl]="notification.profileimageurlfrom" [fullname]="notification.userfromfullname"
|
||||||
[userId]="notification.useridfrom">
|
[userId]="notification.useridfrom">
|
||||||
|
@ -56,13 +47,12 @@
|
||||||
<core-format-text [text]="notification.subject" contextLevel="system" [contextInstanceId]="0" [wsNotFiltered]="true">
|
<core-format-text [text]="notification.subject" contextLevel="system" [contextInstanceId]="0" [wsNotFiltered]="true">
|
||||||
</core-format-text>
|
</core-format-text>
|
||||||
</p>
|
</p>
|
||||||
<p *ngIf="notification.useridfrom > 0">{{ notification.userfromfullname }}</p>
|
<p>{{ notification.timecreated | coreTimeAgo }}<ng-container *ngIf="notification.useridfrom > 0"> · {{
|
||||||
|
notification.userfromfullname }}</ng-container>
|
||||||
|
</p>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
<ion-note slot="end">
|
<ion-note slot="end" *ngIf="!notification.timeread">
|
||||||
{{ notification.timecreated | coreDateDayOrTime }}
|
|
||||||
<span *ngIf="!notification.timeread">
|
|
||||||
<ion-icon name="fas-circle" color="primary" aria-hidden="true"></ion-icon>
|
<ion-icon name="fas-circle" color="primary" aria-hidden="true"></ion-icon>
|
||||||
</span>
|
|
||||||
</ion-note>
|
</ion-note>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
|
||||||
|
@ -72,4 +62,15 @@
|
||||||
<core-infinite-loading [enabled]="canLoadMore" (action)="loadMoreNotifications($event)" [error]="loadMoreError">
|
<core-infinite-loading [enabled]="canLoadMore" (action)="loadMoreNotifications($event)" [error]="loadMoreError">
|
||||||
</core-infinite-loading>
|
</core-infinite-loading>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="mark-all-as-read" slot="fixed" collapsible-footer appearOnBottom>
|
||||||
|
<ion-chip *ngIf="notificationsLoaded && canMarkAllNotificationsAsRead" [disabled]="loadingMarkAllNotificationsAsRead"
|
||||||
|
color="primary" (click)="markAllNotificationsAsRead()">
|
||||||
|
<ion-icon name="fas-eye" aria-hidden="true" *ngIf="!loadingMarkAllNotificationsAsRead"></ion-icon>
|
||||||
|
<ion-spinner [attr.aria-label]="'core.loading' | translate" *ngIf="loadingMarkAllNotificationsAsRead">
|
||||||
|
</ion-spinner>
|
||||||
|
{{ 'addon.notifications.markallread' | translate }}
|
||||||
|
</ion-chip>
|
||||||
|
</div>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
@import "~theme/globals";
|
||||||
|
|
||||||
|
ion-item {
|
||||||
|
ion-label {
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
p.item-heading {
|
||||||
|
font-size: 14px;
|
||||||
|
-webkit-line-clamp: 3;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
display: -webkit-box;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ion-note {
|
||||||
|
margin: 0;
|
||||||
|
@include padding-horizontal(8px, 0);
|
||||||
|
padding-top: 12px;
|
||||||
|
|
||||||
|
ion-icon {
|
||||||
|
font-size: 6px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[slot=start] {
|
||||||
|
align-self: start;
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
--icon-size: 16px;
|
||||||
|
--extra-icon-size: 12px;
|
||||||
|
--core-avatar-size: 32px;
|
||||||
|
|
||||||
|
div.core-notification-icon,
|
||||||
|
core-mod-icon.core-notification-icon {
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mark-all-as-read {
|
||||||
|
padding-bottom: 16px;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
display: flex;
|
||||||
|
background: transparent;
|
||||||
|
box-shadow: none;
|
||||||
|
pointer-events: none;
|
||||||
|
|
||||||
|
ion-chip.ion-color {
|
||||||
|
pointer-events: all;
|
||||||
|
margin: 0 auto;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, .4);
|
||||||
|
|
||||||
|
ion-spinner {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
@include margin-horizontal(0, 8px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ion-content::part(scroll) {
|
||||||
|
padding-bottom: 44px;
|
||||||
|
}
|
|
@ -39,7 +39,7 @@ import { CoreTimeUtils } from '@services/utils/time';
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'page-addon-notifications-list',
|
selector: 'page-addon-notifications-list',
|
||||||
templateUrl: 'list.html',
|
templateUrl: 'list.html',
|
||||||
styleUrls: ['../../notifications.scss'],
|
styleUrls: ['list.scss', '../../notifications.scss'],
|
||||||
})
|
})
|
||||||
export class AddonNotificationsListPage implements OnInit, OnDestroy {
|
export class AddonNotificationsListPage implements OnInit, OnDestroy {
|
||||||
|
|
||||||
|
@ -157,22 +157,6 @@ export class AddonNotificationsListPage implements OnInit, OnDestroy {
|
||||||
await this.refreshNotifications();
|
await this.refreshNotifications();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Mark notifications as read.
|
|
||||||
*
|
|
||||||
* @param notification Array of notification objects.
|
|
||||||
* @return Promise resolved when done.
|
|
||||||
*/
|
|
||||||
protected async markNotificationAsRead(notification: AddonNotificationsNotificationToRender): Promise<void> {
|
|
||||||
const updated = await AddonNotificationsHelper.markNotificationAsRead(notification);
|
|
||||||
|
|
||||||
if (!updated) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.loadMarkAllAsReadButton();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load mark all notifications as read button.
|
* Load mark all notifications as read button.
|
||||||
*
|
*
|
||||||
|
|
|
@ -11,9 +11,8 @@
|
||||||
<ion-content>
|
<ion-content>
|
||||||
<core-loading [hideUntil]="loaded">
|
<core-loading [hideUntil]="loaded">
|
||||||
<div class="list-item-limited-width">
|
<div class="list-item-limited-width">
|
||||||
<ion-card>
|
|
||||||
|
|
||||||
<ion-item class="ion-text-wrap">
|
<ion-item class="ion-text-wrap core-notification-title" lines="full">
|
||||||
<core-user-avatar *ngIf="userIdFrom > 0" slot="start" [userId]="userIdFrom" [profileUrl]="profileImageUrlFrom"
|
<core-user-avatar *ngIf="userIdFrom > 0" slot="start" [userId]="userIdFrom" [profileUrl]="profileImageUrlFrom"
|
||||||
[fullname]="userFromFullName">
|
[fullname]="userFromFullName">
|
||||||
<div class="core-avatar-extra-img" *ngIf="iconUrl && !modname">
|
<div class="core-avatar-extra-img" *ngIf="iconUrl && !modname">
|
||||||
|
@ -27,29 +26,27 @@
|
||||||
<div class="core-notification-icon" *ngIf="!modname" slot="start">
|
<div class="core-notification-icon" *ngIf="!modname" slot="start">
|
||||||
<img [src]="iconUrl" alt="" role="presentation">
|
<img [src]="iconUrl" alt="" role="presentation">
|
||||||
</div>
|
</div>
|
||||||
<core-mod-icon *ngIf="modname" [modicon]="iconUrl" [modname]="modname" [showAlt]="false"
|
<core-mod-icon *ngIf="modname" [modicon]="iconUrl" [modname]="modname" [showAlt]="false" class="core-notification-icon"
|
||||||
class="core-notification-icon" slot="start">
|
slot="start">
|
||||||
</core-mod-icon>
|
</core-mod-icon>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<ion-card-subtitle *ngIf="userIdFrom > 0">{{ userFromFullName }}</ion-card-subtitle>
|
<p class="item-heading">
|
||||||
<ion-card-title>
|
|
||||||
<core-format-text [text]="subject" contextLevel="system" [contextInstanceId]="0" [wsNotFiltered]="true">
|
<core-format-text [text]="subject" contextLevel="system" [contextInstanceId]="0" [wsNotFiltered]="true">
|
||||||
</core-format-text>
|
</core-format-text>
|
||||||
</ion-card-title>
|
</p>
|
||||||
|
<p>{{ timecreated | coreTimeAgo }}<ng-container *ngIf="userIdFrom > 0"> · {{
|
||||||
|
userFromFullName }}</ng-container>
|
||||||
|
</p>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
<ion-note slot="end" *ngIf="timecreated">
|
|
||||||
{{ timecreated | coreDateDayOrTime }}
|
|
||||||
</ion-note>
|
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item class="ion-text-wrap">
|
<ion-item class="ion-text-wrap core-notification-body">
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<core-format-text [text]="content | coreCreateLinks" contextLevel="system" [contextInstanceId]="0">
|
<core-format-text [text]="content | coreCreateLinks" contextLevel="system" [contextInstanceId]="0">
|
||||||
</core-format-text>
|
</core-format-text>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
</ion-card>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div collapsible-footer appearOnBottom *ngIf="loaded && actions && actions.length > 0" slot="fixed">
|
<div collapsible-footer appearOnBottom *ngIf="loaded && actions && actions.length > 0" slot="fixed">
|
||||||
|
|
|
@ -2,6 +2,24 @@
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
|
|
||||||
|
.core-notification-title {
|
||||||
|
[slot=start] {
|
||||||
|
align-self: start;
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
p.item-heading {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.core-notification-body {
|
||||||
|
core-format-text {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
@ -65,4 +83,5 @@
|
||||||
background-color: var(--gray-200);
|
background-color: var(--gray-200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue