1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-21 09:38:01 +02:00

Desktop, Mobile: Add Joplin Cloud account information to configuration screen (#10553)

This commit is contained in:
pedr 2024-06-12 11:14:32 -03:00 committed by GitHub
parent 7d0cc675aa
commit 889c395818
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 173 additions and 30 deletions

View File

@ -597,6 +597,7 @@ packages/app-mobile/components/getResponsiveValue.js
packages/app-mobile/components/global-style.js
packages/app-mobile/components/screens/ConfigScreen/ConfigScreen.js
packages/app-mobile/components/screens/ConfigScreen/FileSystemPathSelector.js
packages/app-mobile/components/screens/ConfigScreen/JoplinCloudConfig.js
packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/ExportDebugReportButton.js
packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/ExportProfileButton.js
packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/NoteExportButton.test.js
@ -1243,7 +1244,8 @@ packages/lib/utils/ipc/utils/mergeCallbacksAndSerializable.js
packages/lib/utils/ipc/utils/separateCallbacksFromSerializable.test.js
packages/lib/utils/ipc/utils/separateCallbacksFromSerializable.js
packages/lib/utils/ipc/utils/separateCallbacksFromSerializableArray.js
packages/lib/utils/joplinCloud.js
packages/lib/utils/joplinCloud/index.js
packages/lib/utils/joplinCloud/types.js
packages/lib/utils/processStartFlags.js
packages/lib/utils/replaceUnsupportedCharacters.test.js
packages/lib/utils/replaceUnsupportedCharacters.js

4
.gitignore vendored
View File

@ -576,6 +576,7 @@ packages/app-mobile/components/getResponsiveValue.js
packages/app-mobile/components/global-style.js
packages/app-mobile/components/screens/ConfigScreen/ConfigScreen.js
packages/app-mobile/components/screens/ConfigScreen/FileSystemPathSelector.js
packages/app-mobile/components/screens/ConfigScreen/JoplinCloudConfig.js
packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/ExportDebugReportButton.js
packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/ExportProfileButton.js
packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/NoteExportButton.test.js
@ -1222,7 +1223,8 @@ packages/lib/utils/ipc/utils/mergeCallbacksAndSerializable.js
packages/lib/utils/ipc/utils/separateCallbacksFromSerializable.test.js
packages/lib/utils/ipc/utils/separateCallbacksFromSerializable.js
packages/lib/utils/ipc/utils/separateCallbacksFromSerializableArray.js
packages/lib/utils/joplinCloud.js
packages/lib/utils/joplinCloud/index.js
packages/lib/utils/joplinCloud/types.js
packages/lib/utils/processStartFlags.js
packages/lib/utils/replaceUnsupportedCharacters.test.js
packages/lib/utils/replaceUnsupportedCharacters.js

View File

@ -10,3 +10,24 @@
padding: calc(var(--joplin-font-size) * 0.8);
}
}
.joplin-cloud-account-information {
margin-bottom: var(--joplin-margin);
table {
margin-bottom: var(--joplin-margin);
border: none;
td {
border: none;
border-bottom: 1px solid var(--joplin-border-color4);
padding: var(--joplin-font-size);
}
tr:last-child {
td {
border: none;
}
}
}
}

View File

@ -4,10 +4,14 @@ import { _ } from '@joplin/lib/locale';
import { clipboard } from 'electron';
import Button from './Button/Button';
import { Fragment } from 'react';
import { accountTypeToString } from '@joplin/lib/utils/joplinCloud/types';
import bridge from '../services/bridge';
type JoplinCloudConfigScreenProps = {
inboxEmail: string;
joplinCloudAccountType: number;
userEmail: string;
joplinCloudWebsite: string;
};
const JoplinCloudConfigScreen = (props: JoplinCloudConfigScreenProps) => {
@ -17,8 +21,29 @@ const JoplinCloudConfigScreen = (props: JoplinCloudConfigScreenProps) => {
const isEmailToNoteAvailableInAccount = props.joplinCloudAccountType !== 1;
const goToJoplinCloudProfile = async () => {
await bridge().openExternal(`${props.joplinCloudWebsite}/users/me`);
};
return (
<div>
<div className="joplin-cloud-account-information">
<h2>{_('Account information')}</h2>
<table>
<tbody>
<tr>
<td><strong>{_('Account type')}</strong></td>
<td>{accountTypeToString(props.joplinCloudAccountType)}</td>
</tr>
<tr>
<td><strong>{_('Email')}</strong></td>
<td>{props.userEmail}</td>
</tr>
</tbody>
</table>
<Button onClick={goToJoplinCloudProfile} title={_('Go to Joplin Cloud profile')}/>
</div>
<h2>{_('Email to note')}</h2>
<p>{_('Any email sent to this address will be converted into a note and added to your collection. The note will be saved into the Inbox notebook')}</p>
{
@ -38,6 +63,8 @@ const mapStateToProps = (state: AppState) => {
return {
inboxEmail: state.settings['sync.10.inboxEmail'],
joplinCloudAccountType: state.settings['sync.10.accountType'],
userEmail: state.settings['sync.10.userEmail'],
joplinCloudWebsite: state.settings['sync.10.website'],
};
};

View File

@ -34,6 +34,7 @@ import NoteImportButton, { importButtonDefaultTitle, importButtonDescription } f
import SectionDescription from './SectionDescription';
import EnablePluginSupportPage from './plugins/EnablePluginSupportPage';
import getVersionInfoText from '../../../utils/getVersionInfoText';
import JoplinCloudConfig, { emailToNoteDescription, emailToNoteLabel } from './JoplinCloudConfig';
interface ConfigScreenState {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
@ -538,33 +539,16 @@ class ConfigScreenComponent extends BaseScreenComponent<ConfigScreenProps, Confi
}
if (section.name === 'joplinCloud') {
const label = _('Email to note');
const description = _('Any email sent to this address will be converted into a note and added to your collection. The note will be saved into the Inbox notebook');
const isEmailToNoteAvailableInAccount = this.props.settings['sync.10.accountType'] !== 1;
const inboxEmailValue = isEmailToNoteAvailableInAccount ? this.props.settings['sync.10.inboxEmail'] : '-';
addSettingComponent(
<View key="joplinCloud">
<View style={this.styles().styleSheet.settingContainerNoBottomBorder}>
<Text style={this.styles().styleSheet.settingText}>{label}</Text>
<Text style={this.styles().styleSheet.settingTextEmphasis}>{inboxEmailValue}</Text>
</View>
{
!isEmailToNoteAvailableInAccount && (
<View style={this.styles().styleSheet.settingContainerNoBottomBorder}>
<Text style={this.styles().styleSheet.descriptionAlert}>{_('Your account doesn\'t have access to this feature')}</Text>
</View>
)
}
{
this.renderButton(
'sync.10.inboxEmail',
_('Copy to clipboard'),
() => isEmailToNoteAvailableInAccount && Clipboard.setString(this.props.settings['sync.10.inboxEmail']),
{ description, disabled: !isEmailToNoteAvailableInAccount },
)
}
</View>,
[label, description],
<JoplinCloudConfig
key="joplin-cloud-config"
accountType={this.props.settings['sync.10.accountType']}
inboxEmail={this.props.settings['sync.10.inboxEmail']}
userEmail={this.props.settings['sync.10.userEmail']}
website={this.props.settings['sync.10.website']}
styles={this.styles()}
/>,
[emailToNoteDescription(), emailToNoteLabel()],
);
}

View File

@ -0,0 +1,87 @@
import { _ } from '@joplin/lib/locale';
import * as React from 'react';
import { useCallback } from 'react';
import { View, Text, Linking } from 'react-native';
import Clipboard from '@react-native-clipboard/clipboard';
import SettingsButton from './SettingsButton';
import { accountTypeToString } from '@joplin/lib/utils/joplinCloud/types';
import { LinkButton } from '../../buttons';
import { ConfigScreenStyles } from './configScreenStyles';
import { Divider } from 'react-native-paper';
import Logger from '@joplin/utils/Logger';
const logger = Logger.create('JoplinCloudConfig');
type JoplinCloudConfigProps = {
styles: ConfigScreenStyles;
accountType: string;
inboxEmail: string;
website: string;
userEmail: string;
};
export const emailToNoteLabel = () => _('Email to note');
export const emailToNoteDescription = () => _('Any email sent to this address will be converted into a note and added to your collection. The note will be saved into the Inbox notebook');
const JoplinCloudConfig = (props: JoplinCloudConfigProps) => {
const isEmailToNoteAvailableInAccount = props.accountType !== '1';
const inboxEmailValue = props.inboxEmail ?? '-';
const goToJoplinCloudProfile = useCallback(async () => {
await Linking.openURL(`${props.website}/users/me`);
}, [props.website]);
const accountTypeName = () => {
try {
if (!props.accountType) return 'Unknown';
return accountTypeToString(parseInt(props.accountType, 10));
} catch (error) {
logger.error(error);
return 'Unknown';
}
};
return (
<View>
<View style={props.styles.styleSheet.settingContainerNoBottomBorder}>
<Text style={props.styles.styleSheet.settingTextEmphasis}>{_('Account information')}</Text>
</View>
<View style={props.styles.styleSheet.settingContainerNoBottomBorder}>
<Text style={props.styles.styleSheet.settingText}>{_('Account type')}</Text>
<Text style={props.styles.styleSheet.settingTextEmphasis}>{accountTypeName()}</Text>
</View>
<View style={props.styles.styleSheet.settingContainerNoBottomBorder}>
<Text style={props.styles.styleSheet.settingText}>{_('Email')}</Text>
<Text selectable style={props.styles.styleSheet.settingTextEmphasis}>{props.userEmail}</Text>
</View>
<LinkButton onPress={goToJoplinCloudProfile}>
{_('Go to Joplin Cloud profile')}
</LinkButton>
<Divider bold />
<View style={props.styles.styleSheet.settingContainerNoBottomBorder}>
<Text style={props.styles.styleSheet.settingText}>{emailToNoteLabel()}</Text>
<Text style={props.styles.styleSheet.settingTextEmphasis}>{inboxEmailValue}</Text>
</View>
{
!isEmailToNoteAvailableInAccount && (
<View style={props.styles.styleSheet.settingContainerNoBottomBorder}>
<Text style={props.styles.styleSheet.descriptionAlert}>{_('Your account doesn\'t have access to this feature')}</Text>
</View>
)
}
<SettingsButton
title={_('Copy to clipboard')}
clickHandler={() => isEmailToNoteAvailableInAccount && Clipboard.setString(props.inboxEmail)}
description={emailToNoteDescription()}
statusComponent={undefined}
styles={props.styles}
disabled={!isEmailToNoteAvailableInAccount}
/>
</View>
);
};
export default JoplinCloudConfig;

View File

@ -765,6 +765,8 @@ class Setting extends BaseModel {
'sync.10.accountType': { value: 0, type: SettingItemType.Int, public: false },
'sync.10.userEmail': { value: '', type: SettingItemType.String, public: false },
'sync.5.syncTargets': { value: {}, type: SettingItemType.Object, public: false },
'sync.resourceDownloadMode': {

View File

@ -1,6 +1,6 @@
import * as fs from 'fs-extra';
import markdownUtils, { MarkdownTableHeader, MarkdownTableRow } from '../markdownUtils';
import { _ } from '../locale';
import markdownUtils, { MarkdownTableHeader, MarkdownTableRow } from '../../markdownUtils';
import { _ } from '../../locale';
import { htmlentities } from '@joplin/utils/html';
type FeatureId = string;

View File

@ -0,0 +1,16 @@
enum AccountType {
Default = 0,
Basic = 1,
Pro = 2,
Team = 3,
}
// eslint-disable-next-line import/prefer-default-export
export function accountTypeToString(accountType: AccountType): string {
if (accountType === AccountType.Default) return 'Default';
if (accountType === AccountType.Basic) return 'Basic';
if (accountType === AccountType.Pro) return 'Pro';
if (accountType === AccountType.Team) return 'Team';
const exhaustivenessCheck: never = accountType;
throw new Error(`Invalid type: ${exhaustivenessCheck}`);
}

View File

@ -13,6 +13,7 @@ interface UserApiResponse {
inbox_email?: string;
can_use_share_permissions?: number;
account_type?: number;
email: string;
}
const userFetcher = async () => {
@ -40,6 +41,7 @@ const userFetcher = async () => {
Setting.setValue('sync.10.inboxEmail', owner.inbox_email ? owner.inbox_email : '');
Setting.setValue('sync.10.canUseSharePermissions', !!owner.can_use_share_permissions);
Setting.setValue('sync.10.accountType', owner.account_type);
Setting.setValue('sync.10.userEmail', owner.email);
};
// Listen to the event only once