1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-24 10:27:10 +02:00

Mobile: Display icon for all notebooks if at least one notebook has an icon

This commit is contained in:
Laurent Cozic 2022-10-11 12:46:40 +01:00
parent f28c1bc6ba
commit ec97dd8c60
4 changed files with 77 additions and 64 deletions

View File

@ -152,7 +152,7 @@ const SidebarComponent = (props: Props) => {
// visual alignment is correct for all folders, otherwise the folder tree // visual alignment is correct for all folders, otherwise the folder tree
// looks messy. // looks messy.
const showFolderIcons = useMemo(() => { const showFolderIcons = useMemo(() => {
return !!props.folders.find((f: FolderEntity) => !!f.icon); return Folder.shouldShowFolderIcons(props.folders);
}, [props.folders]); }, [props.folders]);
const getSelectedItem = useCallback(() => { const getSelectedItem = useCallback(() => {

View File

@ -1,5 +1,5 @@
const React = require('react'); const React = require('react');
import { useMemo, useEffect } from 'react'; import { useMemo, useEffect, useCallback } from 'react';
const { Easing, Animated, TouchableOpacity, Text, StyleSheet, ScrollView, View, Alert, Image } = require('react-native'); const { Easing, Animated, TouchableOpacity, Text, StyleSheet, ScrollView, View, Alert, Image } = require('react-native');
const { connect } = require('react-redux'); const { connect } = require('react-redux');
const Icon = require('react-native-vector-icons/Ionicons').default; const Icon = require('react-native-vector-icons/Ionicons').default;
@ -11,6 +11,8 @@ const { themeStyle } = require('./global-style.js');
const shared = require('@joplin/lib/components/shared/side-menu-shared.js'); const shared = require('@joplin/lib/components/shared/side-menu-shared.js');
import { FolderEntity, FolderIcon } from '@joplin/lib/services/database/types'; import { FolderEntity, FolderIcon } from '@joplin/lib/services/database/types';
import { AppState } from '../utils/types'; import { AppState } from '../utils/types';
import Setting from '@joplin/lib/models/Setting';
import { reg } from '@joplin/lib/registry';
Icon.loadFont(); Icon.loadFont();
@ -39,6 +41,8 @@ const syncIconRotation = syncIconRotationValue.interpolate({
let syncIconAnimation: any; let syncIconAnimation: any;
const SideMenuContentComponent = (props: Props) => { const SideMenuContentComponent = (props: Props) => {
const alwaysShowFolderIcons = useMemo(() => Folder.shouldShowFolderIcons(props.folders), [props.folders]);
const styles_ = useMemo(() => { const styles_ = useMemo(() => {
const theme = themeStyle(props.themeId); const theme = themeStyle(props.themeId);
@ -215,13 +219,72 @@ const SideMenuContentComponent = (props: Props) => {
}); });
}; };
const synchronize_press = async () => { const performSync = useCallback(async () => {
const actionDone = await shared.synchronize_press(this); const action = props.syncStarted ? 'cancel' : 'start';
if (!Setting.value('sync.target')) {
props.dispatch({
type: 'SIDE_MENU_CLOSE',
});
props.dispatch({
type: 'NAV_GO',
routeName: 'Config',
sectionName: 'sync',
});
return 'init';
}
if (!(await reg.syncTarget().isAuthenticated())) {
if (reg.syncTarget().authRouteName()) {
props.dispatch({
type: 'NAV_GO',
routeName: reg.syncTarget().authRouteName(),
});
return 'auth';
}
reg.logger().error('Not authenticated with sync target - please check your credentials.');
return 'error';
}
let sync = null;
try {
sync = await reg.syncTarget().synchronizer();
} catch (error) {
reg.logger().error('Could not initialise synchroniser: ');
reg.logger().error(error);
error.message = `Could not initialise synchroniser: ${error.message}`;
props.dispatch({
type: 'SYNC_REPORT_UPDATE',
report: { errors: [error] },
});
return 'error';
}
if (action === 'cancel') {
void sync.cancel();
return 'cancel';
} else {
void reg.scheduleSync(0);
return 'sync';
}
}, [props.syncStarted, props.dispatch]);
const synchronize_press = useCallback(async () => {
const actionDone = await performSync();
if (actionDone === 'auth') props.dispatch({ type: 'SIDE_MENU_CLOSE' }); if (actionDone === 'auth') props.dispatch({ type: 'SIDE_MENU_CLOSE' });
}; }, [performSync, props.dispatch]);
const renderFolderIcon = (theme: any, folderIcon: FolderIcon) => { const renderFolderIcon = (theme: any, folderIcon: FolderIcon) => {
if (!folderIcon) return <Icon name="folder-outline" style={styles_.emptyFolderIcon} />; if (!folderIcon) {
if (alwaysShowFolderIcons) {
return <Icon name="folder-outline" style={styles_.emptyFolderIcon} />;
} else {
return null;
}
}
if (folderIcon.type === 1) { // FolderIconType.Emoji if (folderIcon.type === 1) { // FolderIconType.Emoji
return <Text style={{ fontSize: theme.fontSize, marginRight: 4 }}>{folderIcon.emoji}</Text>; return <Text style={{ fontSize: theme.fontSize, marginRight: 4 }}>{folderIcon.emoji}</Text>;
@ -381,8 +444,6 @@ const SideMenuContentComponent = (props: Props) => {
const theme = themeStyle(props.themeId); const theme = themeStyle(props.themeId);
// const showFolderIcons = Folder.shouldShowFolderIcons(props.folders);
// HACK: inner height of ScrollView doesn't appear to be calculated correctly when // HACK: inner height of ScrollView doesn't appear to be calculated correctly when
// using padding. So instead creating blank elements for padding bottom and top. // using padding. So instead creating blank elements for padding bottom and top.
items.push(<View style={{ height: theme.marginTop }} key="bottom_top_hack" />); items.push(<View style={{ height: theme.marginTop }} key="bottom_top_hack" />);

View File

@ -1,5 +1,4 @@
const Folder = require('../../models/Folder').default; const Folder = require('../../models/Folder').default;
const Setting = require('../../models/Setting').default;
const BaseModel = require('../../BaseModel').default; const BaseModel = require('../../BaseModel').default;
const shared = {}; const shared = {};
@ -77,59 +76,4 @@ shared.renderTags = function(props, renderItem) {
}; };
}; };
shared.synchronize_press = async function(comp) {
const { reg } = require('../../registry.js');
const action = comp.props.syncStarted ? 'cancel' : 'start';
if (!Setting.value('sync.target')) {
comp.props.dispatch({
type: 'SIDE_MENU_CLOSE',
});
comp.props.dispatch({
type: 'NAV_GO',
routeName: 'Config',
sectionName: 'sync',
});
return 'init';
}
if (!(await reg.syncTarget().isAuthenticated())) {
if (reg.syncTarget().authRouteName()) {
comp.props.dispatch({
type: 'NAV_GO',
routeName: reg.syncTarget().authRouteName(),
});
return 'auth';
}
reg.logger().error('Not authenticated with sync target - please check your credentials.');
return 'error';
}
let sync = null;
try {
sync = await reg.syncTarget().synchronizer();
} catch (error) {
reg.logger().error('Could not initialise synchroniser: ');
reg.logger().error(error);
error.message = `Could not initialise synchroniser: ${error.message}`;
comp.props.dispatch({
type: 'SYNC_REPORT_UPDATE',
report: { errors: [error] },
});
return 'error';
}
if (action === 'cancel') {
sync.cancel();
return 'cancel';
} else {
reg.scheduleSync(0);
return 'sync';
}
};
module.exports = shared; module.exports = shared;

View File

@ -782,4 +782,12 @@ export default class Folder extends BaseItem {
}; };
} }
public static shouldShowFolderIcons(folders: FolderEntity[]) {
// If at least one of the folder has an icon, then we display icons for all
// folders (those without one will get the default icon). This is so that
// visual alignment is correct for all folders, otherwise the folder tree
// looks messy.
return !!folders.find(f => !!f.icon);
}
} }