(core) Make mobile the default mode.

Summary:
- Make unsupported browser warning into an unobtrusive one-liner, similar in
  style to notifications.
- Move browser warning details into a support page, linked from "Learn more" link.
- Show different mobile and desktop warnings.
- Once dismissed, remember dismissal for a year rather than just for the session.
- Turn the Sign-In button (for anon users) into a menu (for the sake of exposing
  the Toggle Mobile Mode option)
- Improve styling of HomeIntro screens when on small screen.
- Flip the default for setting mobile viewport to true

Test Plan: Added minor unittest for localStorageBoolObs; fixed other affected tests.

Reviewers: paulfitz

Reviewed By: paulfitz

Differential Revision: https://phab.getgrist.com/D2738
This commit is contained in:
Dmitry S
2021-02-25 11:11:59 -05:00
parent 31ffd21b4e
commit d8d1a91beb
8 changed files with 119 additions and 76 deletions

View File

@@ -6,7 +6,7 @@ import {showDocSettingsModal} from 'app/client/ui/DocumentSettings';
import {showProfileModal} from 'app/client/ui/ProfileDialog';
import {createUserImage} from 'app/client/ui/UserImage';
import * as viewport from 'app/client/ui/viewport';
import {primaryButtonLink} from 'app/client/ui2018/buttons';
import {primaryButton} from 'app/client/ui2018/buttons';
import {colors, mediaDeviceNotSmall, testId, vars} from 'app/client/ui2018/cssVars';
import {icon} from 'app/client/ui2018/icons';
import {menu, menuDivider, menuItem, menuItemLink, menuSubHeader} from 'app/client/ui2018/menus';
@@ -39,9 +39,9 @@ export class AccountWidget extends Disposable {
cssUserIcon(createUserImage(user, 'medium', testId('user-icon')),
menu(() => this._makeAccountMenu(user), {placement: 'bottom-end'}),
) :
primaryButtonLink('Sign in',
{href: getLoginOrSignupUrl(), style: 'margin: 8px'},
testId('user-signin'))
cssSignInButton('Sign in', icon('Collapse'), testId('user-signin'),
menu(() => this._makeAccountMenu(user), {placement: 'bottom-end'}),
)
)
),
testId('dm-account'),
@@ -63,7 +63,7 @@ export class AccountWidget extends Disposable {
* Renders the content of the account menu, with a list of available orgs, settings, and sign-out.
* Note that `user` should NOT be anonymous (none of the items are really relevant).
*/
private _makeAccountMenu(user: FullUser): DomElementArg[] {
private _makeAccountMenu(user: FullUser|null): DomElementArg[] {
// Opens the user-manager for the org.
const manageUsers = async (org: Organization) => {
const api = this._appModel.api;
@@ -78,7 +78,31 @@ export class AccountWidget extends Disposable {
const currentOrg = this._appModel.currentOrg;
const gristDoc = this._docPageModel ? this._docPageModel.gristDoc.get() : null;
const isBillingManager = Boolean(currentOrg && currentOrg.billingAccount &&
(currentOrg.billingAccount.isManager || user.email === SUPPORT_EMAIL));
(currentOrg.billingAccount.isManager || user?.email === SUPPORT_EMAIL));
// The 'Document Settings' item, when there is an open document.
const documentSettingsItem = (gristDoc ?
menuItem(() => showDocSettingsModal(gristDoc.docInfo, this._docPageModel!), 'Document Settings',
testId('dm-doc-settings')) :
null);
// The item to toggle mobile mode (presence of viewport meta tag).
const mobileModeToggle = menuItem(viewport.toggleViewport,
cssSmallDeviceOnly.cls(''), // Only show this toggle on small devices.
'Toggle Mobile Mode',
cssCheckmark('Tick', dom.show(viewport.viewportEnabled)),
testId('usermenu-toggle-mobile'),
);
if (!user) {
return [
menuItemLink({href: getLoginOrSignupUrl()}, 'Sign in'),
menuDivider(),
documentSettingsItem,
menuItemLink({href: commonUrls.plans}, 'Pricing'),
mobileModeToggle,
];
}
return [
cssUserInfo(
@@ -89,11 +113,7 @@ export class AccountWidget extends Disposable {
),
menuItem(() => showProfileModal(this._appModel), 'Profile Settings'),
// Enable 'Document Settings' when there is an open document.
(gristDoc ?
menuItem(() => showDocSettingsModal(gristDoc.docInfo, this._docPageModel!), 'Document Settings',
testId('dm-doc-settings')) :
null),
documentSettingsItem,
// Show 'Organization Settings' when on a home page of a valid org.
(!this._docPageModel && currentOrg && !currentOrg.owner ?
@@ -112,12 +132,7 @@ export class AccountWidget extends Disposable {
) :
menuItemLink({href: commonUrls.plans}, 'Upgrade Plan'),
menuItem(viewport.toggleViewport,
cssSmallDeviceOnly.cls(''), // Only show this toggle on small devices.
'Toggle Mobile Mode',
cssCheckmark('Tick', dom.show(viewport.viewportEnabled)),
testId('usermenu-toggle-mobile'),
),
mobileModeToggle,
// TODO Add section ("Here right now") listing icons of other users currently on this doc.
// (See Invision "Panels" near the bottom.)
@@ -246,3 +261,9 @@ const cssSmallDeviceOnly = styled(menuItem, `
}
}
`);
const cssSignInButton = styled(primaryButton, `
display: flex;
margin: 8px;
gap: 4px;
`);

View File

@@ -216,17 +216,9 @@ export const spinner = styled('div', `
`);
export const prefSelectors = styled('div', `
position: absolute;
top: 32px;
right: 64px;
float: right;
display: flex;
align-items: center;
@media ${mediaSmall} {
& {
right: 24px;
}
}
`);
export const sortSelector = styled('div', `

View File

@@ -6,7 +6,7 @@ import {examples} from 'app/client/ui/ExampleInfo';
import {createDocAndOpen, importDocAndOpen} from 'app/client/ui/HomeLeftPane';
import {buildPinnedDoc} from 'app/client/ui/PinnedDocs';
import {bigBasicButton} from 'app/client/ui2018/buttons';
import {colors, testId} from 'app/client/ui2018/cssVars';
import {colors, mediaXSmall, testId} from 'app/client/ui2018/cssVars';
import {icon} from 'app/client/ui2018/icons';
import {cssLink} from 'app/client/ui2018/links';
import {commonUrls} from 'app/common/gristUrls';
@@ -127,6 +127,12 @@ function buildExampleItem(doc: Document, home: HomeModel, view: 'list'|'icons')
const cssIntroSplit = styled(css.docBlock, `
display: flex;
align-items: center;
@media ${mediaXSmall} {
& {
display: block;
}
}
`);
const cssIntroLeft = styled('div', `
@@ -134,6 +140,7 @@ const cssIntroLeft = styled('div', `
overflow: hidden;
max-height: 150px;
text-align: center;
margin: 32px 0;
`);
const cssIntroRight = styled('div', `

View File

@@ -2,7 +2,7 @@ import {isIOS} from 'app/client/lib/browserInfo';
import {localStorageBoolObs} from 'app/client/lib/localStorageObs';
import {dom} from 'grainjs';
export const viewportEnabled = localStorageBoolObs('viewportEnabled');
export const viewportEnabled = localStorageBoolObs('viewportEnabled', true);
export function toggleViewport() {
viewportEnabled.set(!viewportEnabled.get());