From fa9490b02b995dd2fee163bbdc3ea050cc674144 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 2 Nov 2020 17:22:45 +0000 Subject: [PATCH 1/6] Add skeleton UI for Room List when no rooms --- res/css/views/rooms/_RoomSublist.scss | 19 +++++++++++++++++++ .../element-icons/roomlist/skeleton-ui.svg | 5 +++++ res/themes/dark/css/_dark.scss | 1 + res/themes/legacy-dark/css/_legacy-dark.scss | 1 + .../legacy-light/css/_legacy-light.scss | 1 + res/themes/light/css/_light.scss | 1 + src/components/views/rooms/RoomList.tsx | 3 +++ src/components/views/rooms/RoomSublist.tsx | 3 +++ 8 files changed, 34 insertions(+) create mode 100644 res/img/element-icons/roomlist/skeleton-ui.svg diff --git a/res/css/views/rooms/_RoomSublist.scss b/res/css/views/rooms/_RoomSublist.scss index 82bba40167..27c7c7d0f7 100644 --- a/res/css/views/rooms/_RoomSublist.scss +++ b/res/css/views/rooms/_RoomSublist.scss @@ -383,3 +383,22 @@ limitations under the License. .mx_RoomSublist_addRoomTooltip { margin-top: -3px; } + +.mx_RoomSublist_skeletonUI { + position: relative; + margin-left: 4px; + height: 288px; + + &::before { + background: $roomsublist-skeleton-ui-bg; + + width: 100%; + height: 100%; + + content: ''; + position: absolute; + mask-repeat: repeat-y; + mask-size: auto 48px; + mask-image: url('$(res)/img/element-icons/roomlist/skeleton-ui.svg'); + } +} diff --git a/res/img/element-icons/roomlist/skeleton-ui.svg b/res/img/element-icons/roomlist/skeleton-ui.svg new file mode 100644 index 0000000000..e95692536c --- /dev/null +++ b/res/img/element-icons/roomlist/skeleton-ui.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/res/themes/dark/css/_dark.scss b/res/themes/dark/css/_dark.scss index bd709473ef..6350439a4f 100644 --- a/res/themes/dark/css/_dark.scss +++ b/res/themes/dark/css/_dark.scss @@ -117,6 +117,7 @@ $roomlist-filter-active-bg-color: $bg-color; $roomlist-bg-color: rgba(33, 38, 44, 0.90); $roomlist-header-color: $tertiary-fg-color; $roomsublist-divider-color: $primary-fg-color; +$roomsublist-skeleton-ui-bg: linear-gradient(180deg, #3e444c 0%, #3e444c00 100%); $groupFilterPanel-divider-color: $roomlist-header-color; diff --git a/res/themes/legacy-dark/css/_legacy-dark.scss b/res/themes/legacy-dark/css/_legacy-dark.scss index 60d44b1c31..716d8c7385 100644 --- a/res/themes/legacy-dark/css/_legacy-dark.scss +++ b/res/themes/legacy-dark/css/_legacy-dark.scss @@ -114,6 +114,7 @@ $roomlist-filter-active-bg-color: $roomlist-button-bg-color; $roomlist-bg-color: $header-panel-bg-color; $roomsublist-divider-color: $primary-fg-color; +$roomsublist-skeleton-ui-bg: linear-gradient(180deg, #3e444c 0%, #3e444c00 100%); $groupFilterPanel-divider-color: $roomlist-header-color; diff --git a/res/themes/legacy-light/css/_legacy-light.scss b/res/themes/legacy-light/css/_legacy-light.scss index 52fb1c8ef2..8c42c5c97f 100644 --- a/res/themes/legacy-light/css/_legacy-light.scss +++ b/res/themes/legacy-light/css/_legacy-light.scss @@ -181,6 +181,7 @@ $roomlist-filter-active-bg-color: $roomlist-button-bg-color; $roomlist-bg-color: $header-panel-bg-color; $roomlist-header-color: $primary-fg-color; $roomsublist-divider-color: $primary-fg-color; +$roomsublist-skeleton-ui-bg: linear-gradient(180deg, #ffffff 0%, #ffffff00 100%); $groupFilterPanel-divider-color: $roomlist-header-color; diff --git a/res/themes/light/css/_light.scss b/res/themes/light/css/_light.scss index 0c5e271860..5437a6de1c 100644 --- a/res/themes/light/css/_light.scss +++ b/res/themes/light/css/_light.scss @@ -175,6 +175,7 @@ $roomlist-filter-active-bg-color: #ffffff; $roomlist-bg-color: rgba(245, 245, 245, 0.90); $roomlist-header-color: $tertiary-fg-color; $roomsublist-divider-color: $primary-fg-color; +$roomsublist-skeleton-ui-bg: linear-gradient(180deg, #ffffff 0%, #ffffff00 100%); $groupFilterPanel-divider-color: $roomlist-header-color; diff --git a/src/components/views/rooms/RoomList.tsx b/src/components/views/rooms/RoomList.tsx index 3a4d27e666..cd1ad09ab4 100644 --- a/src/components/views/rooms/RoomList.tsx +++ b/src/components/views/rooms/RoomList.tsx @@ -332,6 +332,8 @@ export default class RoomList extends React.PureComponent { return p; }, [] as TagID[]); + const showSkeleton = tagOrder.every(tag => !this.state.sublists[tag]?.length); + for (const orderedTagId of tagOrder) { const orderedRooms = this.state.sublists[orderedTagId] || []; const extraTiles = orderedTagId === DefaultTagID.Invite ? this.renderCommunityInvites() : null; @@ -356,6 +358,7 @@ export default class RoomList extends React.PureComponent { addRoomContextMenu={aesthetics.addRoomContextMenu} isMinimized={this.props.isMinimized} onResize={this.props.onResize} + showSkeleton={showSkeleton} extraBadTilesThatShouldntExist={extraTiles} />); } diff --git a/src/components/views/rooms/RoomSublist.tsx b/src/components/views/rooms/RoomSublist.tsx index d93de47d6b..b5ae3285b9 100644 --- a/src/components/views/rooms/RoomSublist.tsx +++ b/src/components/views/rooms/RoomSublist.tsx @@ -71,6 +71,7 @@ interface IProps { isMinimized: boolean; tagId: TagID; onResize: () => void; + showSkeleton?: boolean; // TODO: Don't use this. It's for community invites, and community invites shouldn't be here. // You should feel bad if you use this. @@ -877,6 +878,8 @@ export default class RoomSublist extends React.Component { ); + } else if (this.props.showSkeleton && this.state.isExpanded) { + content =
; } return ( From ce9d31a77866364be64b5b94c38ab1596fdc3530 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 2 Nov 2020 17:23:05 +0000 Subject: [PATCH 2/6] Add Room List join rooms prompt --- src/components/views/rooms/RoomList.tsx | 29 +++++++++++++++++++------ 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/components/views/rooms/RoomList.tsx b/src/components/views/rooms/RoomList.tsx index cd1ad09ab4..62fd70e1ec 100644 --- a/src/components/views/rooms/RoomList.tsx +++ b/src/components/views/rooms/RoomList.tsx @@ -368,13 +368,28 @@ export default class RoomList extends React.PureComponent { public render() { let explorePrompt: JSX.Element; - if (!this.props.isMinimized && RoomListStore.instance.getFirstNameFilterCondition()) { - explorePrompt =
-
{_t("Can't see what you’re looking for?")}
- - {_t("Explore all public rooms")} - -
; + if (!this.props.isMinimized) { + if (RoomListStore.instance.getFirstNameFilterCondition()) { + explorePrompt =
+
{_t("Can't see what you’re looking for?")}
+ + {_t("Explore all public rooms")} + +
; + } else if (Object.values(this.state.sublists).some(list => list.length > 0)) { + const unfilteredLists = RoomListStore.instance.unfilteredLists + const unfilteredRooms = unfilteredLists[DefaultTagID.Untagged] || []; + const unfilteredHistorical = unfilteredLists[DefaultTagID.Archived] || []; + // show a prompt to join/create rooms if the user is in 0 rooms and no historical + if (unfilteredRooms.length < 1 && unfilteredHistorical < 1) { + explorePrompt =
+
{_t("Use the + to make a new room or explore existing ones below")}
+ + {_t("Explore all public rooms")} + +
; + } + } } const sublists = this.renderSublists(); From 4afa610ee14e38166e0ff53b9ab6706141743e2a Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 2 Nov 2020 17:24:47 +0000 Subject: [PATCH 3/6] Add variant of default home page for justRegistered --- res/css/structures/_HomePage.scss | 66 +++++++++--- res/img/element-icons/camera.svg | 10 ++ src/components/structures/HomePage.tsx | 118 ++++++++++++++++++--- src/components/structures/LoggedInView.tsx | 3 +- src/components/structures/MatrixChat.tsx | 11 +- 5 files changed, 174 insertions(+), 34 deletions(-) create mode 100644 res/img/element-icons/camera.svg diff --git a/res/css/structures/_HomePage.scss b/res/css/structures/_HomePage.scss index 04527bff48..2077582a7d 100644 --- a/res/css/structures/_HomePage.scss +++ b/res/css/structures/_HomePage.scss @@ -50,6 +50,44 @@ limitations under the License. color: $muted-fg-color; } + .mx_HomePage_userAvatar { + position: relative; + width: min-content; + margin: 0 auto; + + &::before, &::after { + content: ''; + position: absolute; + + height: 26px; + width: 26px; + + right: -6px; + bottom: -6px; + } + + &::before { + background-color: $primary-bg-color; + border-radius: 50%; + z-index: 1; + } + + &::after { + background-color: $secondary-fg-color; + mask-position: center; + mask-repeat: no-repeat; + mask-image: url('$(res)/img/element-icons/camera.svg'); + mask-size: 16px; + z-index: 2; + } + + &.mx_HomePage_userAvatar_busy::after { + background: url("$(res)/img/spinner.gif") no-repeat center; + background-size: 80%; + mask: unset; + } + } + .mx_HomePage_default_buttons { margin: 80px auto 0; width: fit-content; @@ -57,49 +95,43 @@ limitations under the License. .mx_AccessibleButton { padding: 73px 8px 15px; // top: 20px top padding + 40px icon + 13px margin - width: 104px; // 120px - 2* 8px - margin: 0 39px; // 55px - 2* 8px + width: 160px; + height: 132px; + margin: 0 20px; position: relative; display: inline-block; border-radius: 8px; vertical-align: top; word-break: break-word; + box-sizing: border-box; font-weight: 600; font-size: $font-15px; line-height: $font-20px; - color: $muted-fg-color; - - &:hover { - color: $accent-color; - background: rgba($accent-color, 0.06); - - &::before { - background-color: $accent-color; - } - } + color: #fff; // on all themes + background-color: $accent-color; &::before { top: 20px; - left: 40px; // (120px-40px)/2 + left: 60px; // (160px-40px)/2 width: 40px; height: 40px; content: ''; position: absolute; - background-color: $muted-fg-color; + background-color: #fff; // on all themes mask-repeat: no-repeat; mask-size: contain; } &.mx_HomePage_button_sendDm::before { - mask-image: url('$(res)/img/feather-customised/message-circle.svg'); + mask-image: url('$(res)/img/element-icons/feedback.svg'); } &.mx_HomePage_button_explore::before { - mask-image: url('$(res)/img/feather-customised/explore.svg'); + mask-image: url('$(res)/img/element-icons/roomlist/explore.svg'); } &.mx_HomePage_button_createGroup::before { - mask-image: url('$(res)/img/feather-customised/group.svg'); + mask-image: url('$(res)/img/element-icons/community-members.svg'); } } } diff --git a/res/img/element-icons/camera.svg b/res/img/element-icons/camera.svg new file mode 100644 index 0000000000..92d1f91dec --- /dev/null +++ b/res/img/element-icons/camera.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/components/structures/HomePage.tsx b/src/components/structures/HomePage.tsx index a42032c9fe..a9c755afc6 100644 --- a/src/components/structures/HomePage.tsx +++ b/src/components/structures/HomePage.tsx @@ -15,20 +15,105 @@ limitations under the License. */ import * as React from "react"; +import {useContext, useRef, useState} from "react"; import AutoHideScrollbar from './AutoHideScrollbar'; -import { getHomePageUrl } from "../../utils/pages"; -import { _t } from "../../languageHandler"; +import {getHomePageUrl} from "../../utils/pages"; +import {_t} from "../../languageHandler"; import SdkConfig from "../../SdkConfig"; import * as sdk from "../../index"; import dis from "../../dispatcher/dispatcher"; -import { Action } from "../../dispatcher/actions"; +import {Action} from "../../dispatcher/actions"; +import {Transition} from "react-transition-group"; +import BaseAvatar from "../views/avatars/BaseAvatar"; +import {OwnProfileStore} from "../../stores/OwnProfileStore"; +import AccessibleButton from "../views/elements/AccessibleButton"; +import Tooltip from "../views/elements/Tooltip"; +import {UPDATE_EVENT} from "../../stores/AsyncStore"; +import {useEventEmitter} from "../../hooks/useEventEmitter"; +import MatrixClientContext from "../../contexts/MatrixClientContext"; +import classNames from "classnames"; +import {ENTERING} from "react-transition-group/Transition"; const onClickSendDm = () => dis.dispatch({action: 'view_create_chat'}); const onClickExplore = () => dis.fire(Action.ViewRoomDirectory); const onClickNewRoom = () => dis.dispatch({action: 'view_create_room'}); -const HomePage = () => { +interface IProps { + justRegistered?: boolean; +} + +const avatarSize = 52; + +const getOwnProfile = (userId: string) => ({ + displayName: OwnProfileStore.instance.displayName || userId, + avatarUrl: OwnProfileStore.instance.getHttpAvatarUrl(avatarSize), +}); + +const UserWelcomeTop = () => { + const cli = useContext(MatrixClientContext); + const userId = cli.getUserId(); + const [ownProfile, setOwnProfile] = useState(getOwnProfile(userId)); + useEventEmitter(OwnProfileStore.instance, UPDATE_EVENT, () => { + setOwnProfile(getOwnProfile(userId)); + }); + const [busy, setBusy] = useState(false); + + const uploadRef = useRef(); + + return
+ { + if (!ev.target.files?.length) return; + setBusy(true); + const file = ev.target.files[0]; + const uri = await cli.uploadContent(file); + await cli.setAvatarUrl(uri); + setBusy(false); + }} + accept="image/*" + /> + + { + uploadRef.current.click(); + }} + > + + + + {state => ( + + )} + + + +

{ _t("Welcome %(name)s", { name: ownProfile.displayName }) }

+

{ _t("Now, lets help you get started") }

+
; +}; + +const HomePage: React.FC = ({ justRegistered = false }) => { const config = SdkConfig.get(); const pageUrl = getHomePageUrl(config); @@ -37,18 +122,27 @@ const HomePage = () => { return ; } - const brandingConfig = config.branding; - let logoUrl = "themes/element/img/logos/element-logo.svg"; - if (brandingConfig && brandingConfig.authHeaderLogoUrl) { - logoUrl = brandingConfig.authHeaderLogoUrl; + let introSection; + if (justRegistered) { + introSection = ; + } else { + const brandingConfig = config.branding; + let logoUrl = "themes/element/img/logos/element-logo.svg"; + if (brandingConfig && brandingConfig.authHeaderLogoUrl) { + logoUrl = brandingConfig.authHeaderLogoUrl; + } + + introSection = + {config.brand} +

{ _t("Welcome to %(appName)s", { appName: config.brand }) }

+

{ _t("Liberate your communication") }

+
; } - const AccessibleButton = sdk.getComponent("elements.AccessibleButton"); + return
- {config.brand -

{ _t("Welcome to %(appName)s", { appName: config.brand || "Element" }) }

-

{ _t("Liberate your communication") }

+ { introSection }
{ _t("Send a Direct Message") } diff --git a/src/components/structures/LoggedInView.tsx b/src/components/structures/LoggedInView.tsx index 03277a84f9..ab5b93794c 100644 --- a/src/components/structures/LoggedInView.tsx +++ b/src/components/structures/LoggedInView.tsx @@ -88,6 +88,7 @@ interface IProps { currentUserId?: string; currentGroupId?: string; currentGroupIsNew?: boolean; + justRegistered?: boolean; } interface IUsageLimit { @@ -573,7 +574,7 @@ class LoggedInView extends React.Component { break; case PageTypes.HomePage: - pageElement = ; + pageElement = ; break; case PageTypes.UserView: diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index f37da03e47..4d154e4332 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -201,6 +201,7 @@ interface IState { roomOobData?: object; viaServers?: string[]; pendingInitialSync?: boolean; + justRegistered?: boolean; } export default class MatrixChat extends React.PureComponent { @@ -479,6 +480,7 @@ export default class MatrixChat extends React.PureComponent { } const newState = { currentUserId: null, + justRegistered: false, }; Object.assign(newState, state); this.setState(newState); @@ -669,7 +671,7 @@ export default class MatrixChat extends React.PureComponent { this.viewWelcome(); break; case 'view_home_page': - this.viewHome(); + this.viewHome(payload.justRegistered); break; case 'view_start_chat_or_reuse': this.chatCreateOrReuse(payload.user_id); @@ -953,10 +955,11 @@ export default class MatrixChat extends React.PureComponent { this.themeWatcher.recheck(); } - private viewHome() { + private viewHome(justRegistered = false) { // The home page requires the "logged in" view, so we'll set that. this.setStateForNewView({ view: Views.LOGGED_IN, + justRegistered, }); this.setPage(PageTypes.HomePage); this.notifyNewScreen('home'); @@ -1190,7 +1193,7 @@ export default class MatrixChat extends React.PureComponent { if (welcomeUserRoom === null) { // We didn't redirect to the welcome user room, so show // the homepage. - dis.dispatch({action: 'view_home_page'}); + dis.dispatch({action: 'view_home_page', justRegistered: true}); } } else if (ThreepidInviteStore.instance.pickBestInvite()) { // The user has a 3pid invite pending - show them that @@ -1203,7 +1206,7 @@ export default class MatrixChat extends React.PureComponent { } else { // The user has just logged in after registering, // so show the homepage. - dis.dispatch({action: 'view_home_page'}); + dis.dispatch({action: 'view_home_page', justRegistered: true}); } } else { this.showScreenAfterLogin(); From 0c14de3017a2c1acd772c6fd5050ea6ce66d0d7d Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 2 Nov 2020 17:25:48 +0000 Subject: [PATCH 4/6] defer some toasts --- src/BasePlatform.ts | 4 ++++ src/MatrixClientPeg.ts | 18 ++++++++++++++++++ src/components/structures/MatrixChat.tsx | 8 +++++--- src/components/structures/RoomView.tsx | 7 +++++++ 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/BasePlatform.ts b/src/BasePlatform.ts index 4d06c5df73..0a1f06f0b3 100644 --- a/src/BasePlatform.ts +++ b/src/BasePlatform.ts @@ -24,6 +24,7 @@ import {ActionPayload} from "./dispatcher/payloads"; import {CheckUpdatesPayload} from "./dispatcher/payloads/CheckUpdatesPayload"; import {Action} from "./dispatcher/actions"; import {hideToast as hideUpdateToast} from "./toasts/UpdateToast"; +import {MatrixClientPeg} from "./MatrixClientPeg"; export const SSO_HOMESERVER_URL_KEY = "mx_sso_hs_url"; export const SSO_ID_SERVER_URL_KEY = "mx_sso_is_url"; @@ -105,6 +106,9 @@ export default abstract class BasePlatform { * @param newVersion the version string to check */ protected shouldShowUpdate(newVersion: string): boolean { + // If the user registered on this client in the last 24 hours then do not show them the update toast + if (MatrixClientPeg.userRegisteredWithinLastHours(24)) return false; + try { const [version, deferUntil] = JSON.parse(localStorage.getItem(UPDATE_DEFER_KEY)); return newVersion !== version || Date.now() > deferUntil; diff --git a/src/MatrixClientPeg.ts b/src/MatrixClientPeg.ts index 5bb10dfa89..2d8c2dd398 100644 --- a/src/MatrixClientPeg.ts +++ b/src/MatrixClientPeg.ts @@ -100,6 +100,12 @@ export interface IMatrixClientPeg { */ currentUserIsJustRegistered(): boolean; + /** + * If the current user has been registered by this device then this + * returns a boolean of whether it was within the last N hours given. + */ + userRegisteredWithinLastHours(hours: number): boolean; + /** * Replace this MatrixClientPeg's client with a client instance that has * homeserver / identity server URLs and active credentials @@ -150,6 +156,9 @@ class _MatrixClientPeg implements IMatrixClientPeg { public setJustRegisteredUserId(uid: string): void { this.justRegisteredUserId = uid; + if (uid) { + window.localStorage.setItem("mx_registration_time", String(new Date().getTime())); + } } public currentUserIsJustRegistered(): boolean { @@ -159,6 +168,15 @@ class _MatrixClientPeg implements IMatrixClientPeg { ); } + public userRegisteredWithinLastHours(hours: number): boolean { + try { + const date = new Date(window.localStorage.getItem("mx_registration_time")); + return ((new Date().getTime() - date.getTime()) / 36e5) <= hours; + } catch (e) { + return false; + } + } + public replaceUsingCreds(creds: IMatrixClientCreds): void { this.currentClientCreds = creds; this.createClient(creds); diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index 4d154e4332..429d60e5bd 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -62,7 +62,7 @@ import DMRoomMap from '../../utils/DMRoomMap'; import ThemeWatcher from "../../settings/watchers/ThemeWatcher"; import { FontWatcher } from '../../settings/watchers/FontWatcher'; import { storeRoomAliasInCache } from '../../RoomAliasCache'; -import { defer, IDeferred } from "../../utils/promise"; +import { defer, IDeferred, sleep } from "../../utils/promise"; import ToastStore from "../../stores/ToastStore"; import * as StorageManager from "../../utils/StorageManager"; import type LoggedInViewType from "./LoggedInView"; @@ -1214,6 +1214,8 @@ export default class MatrixChat extends React.PureComponent { StorageManager.tryPersistStorage(); + // defer the following actions by 30 seconds to not throw them at the user immediately + await sleep(30); if (SettingsStore.getValue("showCookieBar") && (Analytics.canEnable() || CountlyAnalytics.instance.canEnable()) ) { @@ -1346,8 +1348,8 @@ export default class MatrixChat extends React.PureComponent { this.firstSyncComplete = true; this.firstSyncPromise.resolve(); - if (Notifier.shouldShowPrompt()) { - showNotificationsToast(); + if (Notifier.shouldShowPrompt() && !MatrixClientPeg.userRegisteredWithinLastHours(24)) { + showNotificationsToast(false); } dis.fire(Action.FocusComposer); diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 160e9c0ec6..0cb4a5d305 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -74,6 +74,8 @@ import { IThreepidInvite } from "../../stores/ThreepidInviteStore"; import { CallState, CallType, MatrixCall } from "matrix-js-sdk/lib/webrtc/call"; import WidgetStore from "../../stores/WidgetStore"; import {UPDATE_EVENT} from "../../stores/AsyncStore"; +import Notifier from "../../Notifier"; +import {showToast as showNotificationsToast} from "../../toasts/DesktopNotificationsToast"; const DEBUG = false; let debuglog = function(msg: string) {}; @@ -1050,6 +1052,11 @@ export default class RoomView extends React.Component { let joinedOrInvitedMemberCount = room.getJoinedMemberCount() + room.getInvitedMemberCount(); if (countInfluence) joinedOrInvitedMemberCount += countInfluence; this.setState({isAlone: joinedOrInvitedMemberCount === 1}); + + // if they are not alone additionally prompt the user about notifications so they don't miss replies + if (joinedOrInvitedMemberCount > 1 && Notifier.shouldShowPrompt()) { + showNotificationsToast(true); + } } private updateDMState() { From def02aec1227cf304ba2f51347357ff85309d9ee Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 2 Nov 2020 17:25:56 +0000 Subject: [PATCH 5/6] Update copy on some toasts --- src/toasts/DesktopNotificationsToast.ts | 10 +++++----- src/toasts/UpdateToast.tsx | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/toasts/DesktopNotificationsToast.ts b/src/toasts/DesktopNotificationsToast.ts index d8aa7647a3..e10a6d46c6 100644 --- a/src/toasts/DesktopNotificationsToast.ts +++ b/src/toasts/DesktopNotificationsToast.ts @@ -29,15 +29,15 @@ const onReject = () => { const TOAST_KEY = "desktopnotifications"; -export const showToast = () => { +export const showToast = (fromMessageSend: boolean) => { ToastStore.sharedInstance().addOrReplaceToast({ key: TOAST_KEY, - title: _t("Notifications"), + title: fromMessageSend ? _t("Don't miss a reply") : _t("Notifications"), props: { - description: _t("You are not receiving desktop notifications"), - acceptLabel: _t("Enable them now"), + description: _t("Enable desktop notifications"), + acceptLabel: _t("Enable"), onAccept, - rejectLabel: _t("Close"), + rejectLabel: _t("Dismiss"), onReject, }, component: GenericToast, diff --git a/src/toasts/UpdateToast.tsx b/src/toasts/UpdateToast.tsx index dfd06cf3a0..eb35c41512 100644 --- a/src/toasts/UpdateToast.tsx +++ b/src/toasts/UpdateToast.tsx @@ -74,18 +74,18 @@ export const showToast = (version: string, newVersion: string, releaseNotes?: st }; } else { onAccept = installUpdate; - acceptLabel = _t("Restart"); + acceptLabel = _t("Update"); } const brand = SdkConfig.get().brand; ToastStore.sharedInstance().addOrReplaceToast({ key: TOAST_KEY, - title: _t("Upgrade your %(brand)s", { brand }), + title: _t("Update %(brand)s", { brand }), props: { - description: _t("A new version of %(brand)s is available!", { brand }), + description: _t("New version of %(brand)s is available", { brand }), acceptLabel, onAccept, - rejectLabel: _t("Later"), + rejectLabel: _t("Dismiss"), onReject, }, component: GenericToast, From 3a6420b40df6234f572c7eab47a18dbd5c00c6e4 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 2 Nov 2020 17:26:00 +0000 Subject: [PATCH 6/6] i18n --- src/i18n/strings/en_EN.json | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index a461937875..d269eb1dad 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -403,10 +403,10 @@ "Verify all your sessions to ensure your account & messages are safe": "Verify all your sessions to ensure your account & messages are safe", "Review": "Review", "Later": "Later", + "Don't miss a reply": "Don't miss a reply", "Notifications": "Notifications", - "You are not receiving desktop notifications": "You are not receiving desktop notifications", - "Enable them now": "Enable them now", - "Close": "Close", + "Enable desktop notifications": "Enable desktop notifications", + "Enable": "Enable", "Your homeserver has exceeded its user limit.": "Your homeserver has exceeded its user limit.", "Your homeserver has exceeded one of its resource limits.": "Your homeserver has exceeded one of its resource limits.", "Contact your server admin.": "Contact your server admin.", @@ -424,9 +424,8 @@ "What's new?": "What's new?", "What's New": "What's New", "Update": "Update", - "Restart": "Restart", - "Upgrade your %(brand)s": "Upgrade your %(brand)s", - "A new version of %(brand)s is available!": "A new version of %(brand)s is available!", + "Update %(brand)s": "Update %(brand)s", + "New version of %(brand)s is available": "New version of %(brand)s is available", "Guest": "Guest", "There was an error joining the room": "There was an error joining the room", "Sorry, your homeserver is too old to participate in this room.": "Sorry, your homeserver is too old to participate in this room.", @@ -689,7 +688,6 @@ "rooms.": "rooms.", "Manage": "Manage", "Securely cache encrypted messages locally for them to appear in search results.": "Securely cache encrypted messages locally for them to appear in search results.", - "Enable": "Enable", "%(brand)s is missing some components required for securely caching encrypted messages locally. If you'd like to experiment with this feature, build a custom %(brand)s Desktop with search components added.": "%(brand)s is missing some components required for securely caching encrypted messages locally. If you'd like to experiment with this feature, build a custom %(brand)s Desktop with search components added.", "%(brand)s can't securely cache encrypted messages locally while running in a web browser. Use %(brand)s Desktop for encrypted messages to appear in search results.": "%(brand)s can't securely cache encrypted messages locally while running in a web browser. Use %(brand)s Desktop for encrypted messages to appear in search results.", "Connecting to integration manager...": "Connecting to integration manager...", @@ -872,6 +870,7 @@ "Ban list rules - %(roomName)s": "Ban list rules - %(roomName)s", "Server rules": "Server rules", "User rules": "User rules", + "Close": "Close", "You have not ignored anyone.": "You have not ignored anyone.", "You are currently ignoring:": "You are currently ignoring:", "You are not subscribed to any lists": "You are not subscribed to any lists", @@ -1132,6 +1131,7 @@ "Custom Tag": "Custom Tag", "Can't see what you’re looking for?": "Can't see what you’re looking for?", "Explore all public rooms": "Explore all public rooms", + "Use the + to make a new room or explore existing ones below": "Use the + to make a new room or explore existing ones below", "%(count)s results|other": "%(count)s results", "%(count)s results|one": "%(count)s result", "This room": "This room", @@ -2053,6 +2053,10 @@ "Community %(groupId)s not found": "Community %(groupId)s not found", "This homeserver does not support communities": "This homeserver does not support communities", "Failed to load %(groupId)s": "Failed to load %(groupId)s", + "Great, that'll help people know it's you": "Great, that'll help people know it's you", + "Add a photo so people know it's you.": "Add a photo so people know it's you.", + "Welcome %(name)s": "Welcome %(name)s", + "Now, lets help you get started": "Now, lets help you get started", "Welcome to %(appName)s": "Welcome to %(appName)s", "Liberate your communication": "Liberate your communication", "Send a Direct Message": "Send a Direct Message",