MOBILE-3833 notifications: Update styles
parent
6255c86708
commit
c64f0b9353
|
@ -17,20 +17,11 @@
|
|||
</ion-refresher>
|
||||
<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]="
|
||||
notification.timeread
|
||||
? 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"
|
||||
[profileUrl]="notification.profileimageurlfrom" [fullname]="notification.userfromfullname"
|
||||
[userId]="notification.useridfrom">
|
||||
|
@ -56,13 +47,12 @@
|
|||
<core-format-text [text]="notification.subject" contextLevel="system" [contextInstanceId]="0" [wsNotFiltered]="true">
|
||||
</core-format-text>
|
||||
</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-note slot="end">
|
||||
{{ notification.timecreated | coreDateDayOrTime }}
|
||||
<span *ngIf="!notification.timeread">
|
||||
<ion-icon name="fas-circle" color="primary" aria-hidden="true"></ion-icon>
|
||||
</span>
|
||||
<ion-note slot="end" *ngIf="!notification.timeread">
|
||||
<ion-icon name="fas-circle" color="primary" aria-hidden="true"></ion-icon>
|
||||
</ion-note>
|
||||
</ion-item>
|
||||
|
||||
|
@ -72,4 +62,15 @@
|
|||
<core-infinite-loading [enabled]="canLoadMore" (action)="loadMoreNotifications($event)" [error]="loadMoreError">
|
||||
</core-infinite-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>
|
||||
|
|
|
@ -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({
|
||||
selector: 'page-addon-notifications-list',
|
||||
templateUrl: 'list.html',
|
||||
styleUrls: ['../../notifications.scss'],
|
||||
styleUrls: ['list.scss', '../../notifications.scss'],
|
||||
})
|
||||
export class AddonNotificationsListPage implements OnInit, OnDestroy {
|
||||
|
||||
|
@ -157,22 +157,6 @@ export class AddonNotificationsListPage implements OnInit, OnDestroy {
|
|||
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.
|
||||
*
|
||||
|
|
|
@ -11,45 +11,42 @@
|
|||
<ion-content>
|
||||
<core-loading [hideUntil]="loaded">
|
||||
<div class="list-item-limited-width">
|
||||
<ion-card>
|
||||
|
||||
<ion-item class="ion-text-wrap">
|
||||
<core-user-avatar *ngIf="userIdFrom > 0" slot="start" [userId]="userIdFrom" [profileUrl]="profileImageUrlFrom"
|
||||
[fullname]="userFromFullName">
|
||||
<div class="core-avatar-extra-img" *ngIf="iconUrl && !modname">
|
||||
<img [src]="iconUrl" alt="" role="presentation">
|
||||
</div>
|
||||
<core-mod-icon *ngIf="modname" [modicon]="iconUrl" [modname]="modname" [showAlt]="false">
|
||||
</core-mod-icon>
|
||||
</core-user-avatar>
|
||||
<ion-item class="ion-text-wrap core-notification-title" lines="full">
|
||||
<core-user-avatar *ngIf="userIdFrom > 0" slot="start" [userId]="userIdFrom" [profileUrl]="profileImageUrlFrom"
|
||||
[fullname]="userFromFullName">
|
||||
<div class="core-avatar-extra-img" *ngIf="iconUrl && !modname">
|
||||
<img [src]="iconUrl" alt="" role="presentation">
|
||||
</div>
|
||||
<core-mod-icon *ngIf="modname" [modicon]="iconUrl" [modname]="modname" [showAlt]="false">
|
||||
</core-mod-icon>
|
||||
</core-user-avatar>
|
||||
|
||||
<ng-container *ngIf="userIdFrom <= 0 && iconUrl">
|
||||
<div class="core-notification-icon" *ngIf="!modname" slot="start">
|
||||
<img [src]="iconUrl" alt="" role="presentation">
|
||||
</div>
|
||||
<core-mod-icon *ngIf="modname" [modicon]="iconUrl" [modname]="modname" [showAlt]="false"
|
||||
class="core-notification-icon" slot="start">
|
||||
</core-mod-icon>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="userIdFrom <= 0 && iconUrl">
|
||||
<div class="core-notification-icon" *ngIf="!modname" slot="start">
|
||||
<img [src]="iconUrl" alt="" role="presentation">
|
||||
</div>
|
||||
<core-mod-icon *ngIf="modname" [modicon]="iconUrl" [modname]="modname" [showAlt]="false" class="core-notification-icon"
|
||||
slot="start">
|
||||
</core-mod-icon>
|
||||
</ng-container>
|
||||
|
||||
<ion-label>
|
||||
<ion-card-subtitle *ngIf="userIdFrom > 0">{{ userFromFullName }}</ion-card-subtitle>
|
||||
<ion-card-title>
|
||||
<core-format-text [text]="subject" contextLevel="system" [contextInstanceId]="0" [wsNotFiltered]="true">
|
||||
</core-format-text>
|
||||
</ion-card-title>
|
||||
</ion-label>
|
||||
<ion-note slot="end" *ngIf="timecreated">
|
||||
{{ timecreated | coreDateDayOrTime }}
|
||||
</ion-note>
|
||||
</ion-item>
|
||||
<ion-item class="ion-text-wrap">
|
||||
<ion-label>
|
||||
<core-format-text [text]="content | coreCreateLinks" contextLevel="system" [contextInstanceId]="0">
|
||||
<ion-label>
|
||||
<p class="item-heading">
|
||||
<core-format-text [text]="subject" contextLevel="system" [contextInstanceId]="0" [wsNotFiltered]="true">
|
||||
</core-format-text>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
</ion-card>
|
||||
</p>
|
||||
<p>{{ timecreated | coreTimeAgo }}<ng-container *ngIf="userIdFrom > 0"> · {{
|
||||
userFromFullName }}</ng-container>
|
||||
</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item class="ion-text-wrap core-notification-body">
|
||||
<ion-label>
|
||||
<core-format-text [text]="content | coreCreateLinks" contextLevel="system" [contextInstanceId]="0">
|
||||
</core-format-text>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
</div>
|
||||
|
||||
<div collapsible-footer appearOnBottom *ngIf="loaded && actions && actions.length > 0" slot="fixed">
|
||||
|
|
|
@ -2,67 +2,86 @@
|
|||
|
||||
:host {
|
||||
|
||||
h2 {
|
||||
font-weight: bold;
|
||||
.core-notification-title {
|
||||
[slot=start] {
|
||||
align-self: start;
|
||||
margin-top: 16px;
|
||||
}
|
||||
p.item-heading {
|
||||
font-size: 16px;
|
||||
}
|
||||
p {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
core-format-text ::ng-deep {
|
||||
.forumpost {
|
||||
border: 1px solid var(--gray-200);
|
||||
width: 100%;
|
||||
margin: 0 0 1em 0;
|
||||
.core-notification-body {
|
||||
core-format-text {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 10px;
|
||||
}
|
||||
h2 {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.header {
|
||||
background-color: var(--light);
|
||||
core-format-text ::ng-deep {
|
||||
.forumpost {
|
||||
border: 1px solid var(--gray-200);
|
||||
width: 100%;
|
||||
margin: 0 0 1em 0;
|
||||
|
||||
.picture {
|
||||
width: 48px;
|
||||
text-align: center;
|
||||
@include padding-horizontal(4px, 0px);
|
||||
padding-top: 8px;
|
||||
td {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 44px !important;
|
||||
.header {
|
||||
background-color: var(--light);
|
||||
|
||||
.picture {
|
||||
width: 48px;
|
||||
text-align: center;
|
||||
@include padding-horizontal(4px, 0px);
|
||||
padding-top: 8px;
|
||||
|
||||
img {
|
||||
width: 44px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.subject {
|
||||
font-weight: 700;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.subject {
|
||||
font-weight: 700;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.userpicture {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.mdl-right {
|
||||
text-align: end;
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.userpicture {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.mdl-right {
|
||||
text-align: end;
|
||||
a {
|
||||
display: none;
|
||||
}
|
||||
font {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
}
|
||||
|
||||
.commands {
|
||||
display: none;
|
||||
}
|
||||
font {
|
||||
font-size: 0.9em;
|
||||
|
||||
hr {
|
||||
margin-top: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
background-color: var(--gray-200);
|
||||
}
|
||||
}
|
||||
|
||||
.commands {
|
||||
display: none;
|
||||
}
|
||||
|
||||
hr {
|
||||
margin-top: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
background-color: var(--gray-200);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue