Skip to content

Commit

Permalink
Mobile: Implement plugin screen redesign (#10465)
Browse files Browse the repository at this point in the history
  • Loading branch information
personalizedrefrigerator authored Jun 4, 2024
1 parent 19f0b66 commit 06f42e8
Show file tree
Hide file tree
Showing 39 changed files with 1,459 additions and 632 deletions.
21 changes: 16 additions & 5 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,8 @@ packages/app-mobile/components/base-screen.js
packages/app-mobile/components/biometrics/BiometricPopup.js
packages/app-mobile/components/biometrics/biometricAuthenticate.js
packages/app-mobile/components/biometrics/sensorInfo.js
packages/app-mobile/components/buttons/TextButton.js
packages/app-mobile/components/buttons/index.js
packages/app-mobile/components/getResponsiveValue.test.js
packages/app-mobile/components/getResponsiveValue.js
packages/app-mobile/components/global-style.js
Expand All @@ -610,19 +612,28 @@ packages/app-mobile/components/screens/ConfigScreen/SettingsButton.js
packages/app-mobile/components/screens/ConfigScreen/SettingsToggle.js
packages/app-mobile/components/screens/ConfigScreen/configScreenStyles.js
packages/app-mobile/components/screens/ConfigScreen/plugins/EnablePluginSupportPage.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginBox/ActionButton.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginBox/PluginInfoButton.js
packages/app-mobile/components/screens/ConfigScreen/plugins/InstalledPluginBox.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginBox/PluginChips.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginBox/PluginTitle.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginBox/StyledChip.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginBox/index.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginStates.test.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginInfoModal.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginStates.installed.test.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginStates.search.test.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginStates.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginToggle.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginUploadButton.js
packages/app-mobile/components/screens/ConfigScreen/plugins/SearchPlugins.test.js
packages/app-mobile/components/screens/ConfigScreen/plugins/SearchPlugins.js
packages/app-mobile/components/screens/ConfigScreen/plugins/buttons/ActionButton.js
packages/app-mobile/components/screens/ConfigScreen/plugins/buttons/InstallButton.js
packages/app-mobile/components/screens/ConfigScreen/plugins/testUtils/WrappedPluginStates.js
packages/app-mobile/components/screens/ConfigScreen/plugins/testUtils/mockRepositoryApiConstructor.js
packages/app-mobile/components/screens/ConfigScreen/plugins/testUtils/newRepoApi.js
packages/app-mobile/components/screens/ConfigScreen/plugins/testUtils/pluginServiceSetup.js
packages/app-mobile/components/screens/ConfigScreen/plugins/utils/openWebsiteForPlugin.js
packages/app-mobile/components/screens/ConfigScreen/plugins/utils/usePluginCallbacks.js
packages/app-mobile/components/screens/ConfigScreen/plugins/utils/usePluginItem.js
packages/app-mobile/components/screens/ConfigScreen/plugins/utils/useRepoApi.js
packages/app-mobile/components/screens/ConfigScreen/plugins/utils/useUpdateState.js
packages/app-mobile/components/screens/ConfigScreen/types.js
packages/app-mobile/components/screens/JoplinCloudLoginScreen.js
packages/app-mobile/components/screens/LogScreen.js
Expand Down
21 changes: 16 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,8 @@ packages/app-mobile/components/base-screen.js
packages/app-mobile/components/biometrics/BiometricPopup.js
packages/app-mobile/components/biometrics/biometricAuthenticate.js
packages/app-mobile/components/biometrics/sensorInfo.js
packages/app-mobile/components/buttons/TextButton.js
packages/app-mobile/components/buttons/index.js
packages/app-mobile/components/getResponsiveValue.test.js
packages/app-mobile/components/getResponsiveValue.js
packages/app-mobile/components/global-style.js
Expand All @@ -589,19 +591,28 @@ packages/app-mobile/components/screens/ConfigScreen/SettingsButton.js
packages/app-mobile/components/screens/ConfigScreen/SettingsToggle.js
packages/app-mobile/components/screens/ConfigScreen/configScreenStyles.js
packages/app-mobile/components/screens/ConfigScreen/plugins/EnablePluginSupportPage.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginBox/ActionButton.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginBox/PluginInfoButton.js
packages/app-mobile/components/screens/ConfigScreen/plugins/InstalledPluginBox.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginBox/PluginChips.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginBox/PluginTitle.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginBox/StyledChip.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginBox/index.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginStates.test.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginInfoModal.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginStates.installed.test.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginStates.search.test.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginStates.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginToggle.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginUploadButton.js
packages/app-mobile/components/screens/ConfigScreen/plugins/SearchPlugins.test.js
packages/app-mobile/components/screens/ConfigScreen/plugins/SearchPlugins.js
packages/app-mobile/components/screens/ConfigScreen/plugins/buttons/ActionButton.js
packages/app-mobile/components/screens/ConfigScreen/plugins/buttons/InstallButton.js
packages/app-mobile/components/screens/ConfigScreen/plugins/testUtils/WrappedPluginStates.js
packages/app-mobile/components/screens/ConfigScreen/plugins/testUtils/mockRepositoryApiConstructor.js
packages/app-mobile/components/screens/ConfigScreen/plugins/testUtils/newRepoApi.js
packages/app-mobile/components/screens/ConfigScreen/plugins/testUtils/pluginServiceSetup.js
packages/app-mobile/components/screens/ConfigScreen/plugins/utils/openWebsiteForPlugin.js
packages/app-mobile/components/screens/ConfigScreen/plugins/utils/usePluginCallbacks.js
packages/app-mobile/components/screens/ConfigScreen/plugins/utils/usePluginItem.js
packages/app-mobile/components/screens/ConfigScreen/plugins/utils/useRepoApi.js
packages/app-mobile/components/screens/ConfigScreen/plugins/utils/useUpdateState.js
packages/app-mobile/components/screens/ConfigScreen/types.js
packages/app-mobile/components/screens/JoplinCloudLoginScreen.js
packages/app-mobile/components/screens/LogScreen.js
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ interface Props {
function manifestToItem(manifest: PluginManifest): PluginItem {
return {
manifest: manifest,
installed: true,
enabled: true,
deleted: false,
devMode: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ function usePluginItems(plugins: Plugins, settings: PluginSettings): PluginItem[

output.push({
manifest: plugin.manifest,
installed: true,
enabled: setting.enabled,
deleted: setting.deleted,
devMode: plugin.devMode,
Expand Down
24 changes: 19 additions & 5 deletions packages/app-mobile/components/DismissibleDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,32 @@ import { themeStyle } from './global-style';
import Modal from './Modal';
import { _ } from '@joplin/lib/locale';

export enum DialogSize {
Small = 'small',

// Ideal for panels and dialogs that should be fullscreen even on large devices
Large = 'large',
}

interface Props {
themeId: number;
visible: boolean;
onDismiss: ()=> void;
containerStyle?: ViewStyle;
children: React.ReactNode;

size: DialogSize;
}

const useStyles = (themeId: number, containerStyle: ViewStyle) => {
const useStyles = (themeId: number, containerStyle: ViewStyle, size: DialogSize) => {
const windowSize = useWindowDimensions();

return useMemo(() => {
const theme = themeStyle(themeId);

const maxWidth = size === DialogSize.Large ? Infinity : 500;
const maxHeight = size === DialogSize.Large ? Infinity : 700;

return StyleSheet.create({
webView: {
backgroundColor: 'transparent',
Expand All @@ -38,8 +50,10 @@ const useStyles = (themeId: number, containerStyle: ViewStyle) => {
borderRadius: 12,
padding: 10,

height: windowSize.height * 0.9,
width: windowSize.width * 0.97,
// Use Math.min with width and height -- the maxWidth and maxHeight style
// properties don't seem to limit the size for this.
height: Math.min(maxHeight, windowSize.height * 0.9),
width: Math.min(maxWidth, windowSize.width * 0.97),
flexShrink: 1,

// Center
Expand All @@ -56,11 +70,11 @@ const useStyles = (themeId: number, containerStyle: ViewStyle) => {
flexGrow: 1,
},
});
}, [themeId, windowSize.width, windowSize.height, containerStyle]);
}, [themeId, windowSize.width, windowSize.height, containerStyle, size]);
};

const DismissibleDialog: React.FC<Props> = props => {
const styles = useStyles(props.themeId, props.containerStyle);
const styles = useStyles(props.themeId, props.containerStyle, props.size);

const closeButton = (
<View style={styles.closeButtonContainer}>
Expand Down
81 changes: 81 additions & 0 deletions packages/app-mobile/components/buttons/TextButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import * as React from 'react';
import { ReactNode, useMemo } from 'react';
import { themeStyle } from '../global-style';
import { Button, ButtonProps } from 'react-native-paper';
import { connect } from 'react-redux';
import { AppState } from '../../utils/types';

export enum ButtonType {
Primary,
Secondary,
Delete,
Link,
}

interface Props extends Omit<ButtonProps, 'item'|'onPress'|'children'> {
themeId: number;
type: ButtonType;
onPress: ()=> void;
children: ReactNode;
}

export type TextButtonProps = Omit<Props, 'themeId'>;

const useStyles = ({ themeId }: Props) => {
return useMemo(() => {
const theme = themeStyle(themeId);

const themeOverride = {
secondaryButton: {
colors: {
primary: theme.color4,
outline: theme.color4,
},
},
deleteButton: {
colors: {
primary: theme.destructiveColor,
outline: theme.destructiveColor,
},
},
primaryButton: { },
};

return { themeOverride };
}, [themeId]);
};

const TextButton: React.FC<Props> = props => {
const { themeOverride } = useStyles(props);

let mode: ButtonProps['mode'];
let theme: ButtonProps['theme'];

if (props.type === ButtonType.Primary) {
theme = themeOverride.primaryButton;
mode = 'contained';
} else if (props.type === ButtonType.Secondary) {
theme = themeOverride.secondaryButton;
mode = 'outlined';
} else if (props.type === ButtonType.Delete) {
theme = themeOverride.deleteButton;
mode = 'outlined';
} else if (props.type === ButtonType.Link) {
theme = themeOverride.secondaryButton;
mode = 'text';
} else {
const exhaustivenessCheck: never = props.type;
return exhaustivenessCheck;
}

return <Button
{...props}
theme={theme}
mode={mode}
onPress={props.onPress}
>{props.children}</Button>;
};

export default connect((state: AppState) => {
return { themeId: state.settings.theme };
})(TextButton);
14 changes: 14 additions & 0 deletions packages/app-mobile/components/buttons/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import * as React from 'react';
import TextButton, { ButtonType, TextButtonProps } from './TextButton';

type Props = Omit<TextButtonProps, 'type'>;

const makeTextButtonComponent = (type: ButtonType) => {
return (props: Props) => {
return <TextButton {...props} type={type} />;
};
};

export const PrimaryButton = makeTextButtonComponent(ButtonType.Primary);
export const SecondaryButton = makeTextButtonComponent(ButtonType.Secondary);
export const LinkButton = makeTextButtonComponent(ButtonType.Link);
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { Platform, Linking, View, Switch, ScrollView, Text, TouchableOpacity, Alert, PermissionsAndroid, Dimensions, AccessibilityInfo } from 'react-native';
import Setting, { AppType, SettingItem, SettingMetadataSection } from '@joplin/lib/models/Setting';
import Setting, { AppType, SettingMetadataSection } from '@joplin/lib/models/Setting';
import NavService from '@joplin/lib/services/NavService';
import SearchEngine from '@joplin/lib/services/search/SearchEngine';
import checkPermissions from '../../../utils/checkPermissions';
Expand All @@ -26,7 +26,7 @@ import ExportProfileButton, { exportProfileButtonTitle } from './NoteExportSecti
import SettingComponent from './SettingComponent';
import ExportDebugReportButton, { exportDebugReportTitle } from './NoteExportSection/ExportDebugReportButton';
import SectionSelector from './SectionSelector';
import { Button, TextInput } from 'react-native-paper';
import { TextInput, List } from 'react-native-paper';
import PluginService, { PluginSettings } from '@joplin/lib/services/plugins/PluginService';
import PluginStates, { getSearchText as getPluginStatesSearchText } from './plugins/PluginStates';
import PluginUploadButton, { canInstallPluginsFromFile, buttonLabel as pluginUploadButtonSearchText } from './plugins/PluginUploadButton';
Expand Down Expand Up @@ -389,7 +389,7 @@ class ConfigScreenComponent extends BaseScreenComponent<ConfigScreenProps, Confi
const addSettingComponent = (
component: ReactElement,
relatedText: string|string[],
settingMetadata?: SettingItem,
settingMetadata?: { advanced?: boolean },
) => {
const hiddenBySearch = this.state.searching && !matchesSearchQuery(relatedText);
if (component && !hiddenBySearch) {
Expand Down Expand Up @@ -503,8 +503,10 @@ class ConfigScreenComponent extends BaseScreenComponent<ConfigScreenProps, Confi
key='plugins-install-from-file'
pluginSettings={settings[pluginStatesKey]}
updatePluginStates={updatePluginStates}
styles={this.styles()}
/>,
pluginUploadButtonSearchText(),
{ advanced: true },
);
}
} else {
Expand Down Expand Up @@ -663,19 +665,15 @@ class ConfigScreenComponent extends BaseScreenComponent<ConfigScreenProps, Confi
const renderAdvancedSettings = () => {
if (!advancedSettingComps.length) return null;

const toggleAdvancedLabel = this.state.showAdvancedSettings ? _('Hide Advanced Settings') : _('Show Advanced Settings');
const toggleAdvancedLabel = _('Advanced settings');
return (
<>
<Button
style={{ marginBottom: 20 }}
icon={this.state.showAdvancedSettings ? 'menu-down' : 'menu-right'}
onPress={() => this.setState({ showAdvancedSettings: !this.state.showAdvancedSettings })}
>
<Text>{toggleAdvancedLabel}</Text>
</Button>

<List.Accordion
title={toggleAdvancedLabel}
expanded={this.state.showAdvancedSettings}
onPress={() => this.setState({ showAdvancedSettings: !this.state.showAdvancedSettings })}
>
{this.state.showAdvancedSettings ? advancedSettingComps : null}
</>
</List.Accordion>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { themeStyle } from '../../../global-style';
import * as React from 'react';
import { useMemo } from 'react';
import { Linking, View, StyleSheet, ViewStyle, TextStyle } from 'react-native';
import { Button, Card, Divider, Icon, List, Text } from 'react-native-paper';
import { Card, Divider, Icon, List, Text } from 'react-native-paper';
import { LinkButton, PrimaryButton } from '../../../buttons';

interface Props {
themeId: number;
Expand Down Expand Up @@ -50,26 +51,13 @@ const useStyles = (themeId: number) => {
marginBottom: 0,
},
actionButton: {
borderRadius: 10,
marginLeft: theme.marginLeft * 2,
marginRight: theme.marginRight * 2,
marginBottom: theme.margin,
},
});

const themeOverride = {
secondaryButton: {
colors: {
primary: theme.color4,
outline: theme.color4,
},
},
primaryButton: {
colors: {
primary: theme.color4,
onPrimary: theme.backgroundColor4,
},
},
card: {
colors: {
outline: theme.codeBorderColor,
Expand Down Expand Up @@ -127,8 +115,8 @@ const EnablePluginSupportPage: React.FC<Props> = props => {
{renderCard('source-branch-check', _('Open Source'), _('Most plugins have source code available for review on the plugin website.'))}
{renderCard('flag-remove', _('Report system'), _('We have a system for reporting and removing problematic plugins.'))}
<View>
<Button style={styles.actionButton} theme={themeOverride.secondaryButton} onPress={onLearnMorePress}>{_('Learn more')}</Button>
<Button style={styles.actionButton} theme={themeOverride.primaryButton} mode='contained' onPress={props.onEnablePluginSupport}>{_('Enable plugin support')}</Button>
<LinkButton style={styles.actionButton} onPress={onLearnMorePress}>{_('Learn more')}</LinkButton>
<PrimaryButton style={styles.actionButton} onPress={props.onEnablePluginSupport}>{_('Enable plugin support')}</PrimaryButton>
</View>
</View>
);
Expand Down
Loading

0 comments on commit 06f42e8

Please sign in to comment.