Skip to content

Commit

Permalink
Update new UI for mobile
Browse files Browse the repository at this point in the history
  • Loading branch information
lethemanh committed Jan 3, 2025
1 parent 57dfbaf commit f87d85a
Show file tree
Hide file tree
Showing 18 changed files with 336 additions and 99 deletions.
3 changes: 2 additions & 1 deletion tdrive/frontend/public/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"components.add_mails_workspace.text_area_placeholder": "Enter emails of your users*",
"components.alert.confirm": "Confirm your action",
"components.alert.confirm_click": "Confirm your action by clicking on OK.",
"components.create_folder_modal.hint": "Choose a name for the new folder.",
"components.create_folder_modal.hint": "Create a folder",
"components.create_folder_modal.placeholder": "Folder name",
"components.create_link_modal.button": "Create link",
"components.create_link_modal.hint": "Link name",
Expand All @@ -48,6 +48,7 @@
"components.disk_usage.in_trash": "in trash",
"components.disk_usage.of": "of",
"components.disk_usage.used": "used",
"components.disk_usage.title": "Storage",
"components.dragndrop_info_move_to": "move to",
"components.drive_dropzone.uploading": "Uploading...",
"components.header_path.my_trash": "My Trash",
Expand Down
1 change: 1 addition & 0 deletions tdrive/frontend/public/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"components.disk_usage.in_trash": "dans la corbeille",
"components.disk_usage.of": "sur",
"components.disk_usage.used": "utilisé(s)",
"components.disk_usage.title": "Stockage",
"components.dragndrop_info_move_to": "déplacé vers",
"components.drive_dropzone.uploading": "Téléchargement...",
"components.header_path.my_trash": "Ma corbeille",
Expand Down
1 change: 1 addition & 0 deletions tdrive/frontend/public/locales/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"components.disk_usage.in_trash": "в корзине",
"components.disk_usage.of": "из",
"components.disk_usage.used": "использовано",
"components.disk_usage.title": "хранилище",
"components.dragndrop_info_move_to": "move to",
"components.drive_dropzone.uploading": "Загрузка...",
"components.header_path.my_trash": "Корзина \"Моего диска\"",
Expand Down
3 changes: 2 additions & 1 deletion tdrive/frontend/public/locales/vi.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"components.add_mails_workspace.text_area_placeholder": "Nhập email của người dùng của bạn*",
"components.alert.confirm": "Xác nhận hành động của bạn",
"components.alert.confirm_click": "Xác nhận hành động của bạn bằng cách nhấp vào OK.",
"components.create_folder_modal.hint": "Chọn tên cho thư mục mới.",
"components.create_folder_modal.hint": "Tạo folder",
"components.create_folder_modal.placeholder": "Tên thư mục",
"components.create_link_modal.button": "Tạo liên kết",
"components.create_link_modal.hint": "Tên liên kết",
Expand All @@ -46,6 +46,7 @@
"components.create_modal.upload_folders": "Tải lên thư mục từ thiết bị",
"components.disk_usage.in_trash": "trong thùng rác",
"components.disk_usage.used": "đã sử dụng",
"components.disk_usage.title": "Lưu trữ",
"components.dragndrop_info_move_to": "di chuyển đến",
"components.drive_dropzone.uploading": "Đang tải lên...",
"components.header_path.my_trash": "Thùng rác của tôi",
Expand Down
3 changes: 2 additions & 1 deletion tdrive/frontend/src/app/components/menus/menu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ export default class Menu extends React.Component {
elementRect,
this.props.position,
undefined,
this.props.testClassId
this.props.testClassId,
this.props.enableMobileMenu,
);
this.setState({ isMenuOpen: true }, () => this.open = true);
this.open = true;
Expand Down
62 changes: 42 additions & 20 deletions tdrive/frontend/src/app/components/menus/menus-body-layer.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React from 'react';
import ReactDOM from 'react-dom';

import MenusManager from '@components/menus/menus-manager.jsx';
import MenuComponent from './menu-component.jsx';
import MenusManager from '@components/menus/menus-manager';
import MenuComponent from './menu-component';
import OutsideClickHandler from 'react-outside-click-handler';
import MobileMenu from './mobile-menu';

/*
Where the menu will be displayed, this component should be in app.js (menus should be over all elements of the page)
Expand Down Expand Up @@ -194,24 +195,45 @@ export default class MenusBodyLayer extends React.Component {
marginLeft: item.position.marginLeft,
}}
>
<MenuComponent
withFrame
menu={item.menu}
openAt={item.openAt}
level={item.level}
animationClass={
this.state.menus_manager.willClose || item.willClose
? 'fade_out'
: item.level === 0 || item.positionType
? item.positionType === 'bottom'
? 'skew_in_bottom_nobounce'
: item.left
? 'skew_in_left_nobounce'
: 'skew_in_right_nobounce'
: 'fade_in'
}
testClassId={item.menuTestClassId}
/>
{item.enableMobileMenu ? (
<MobileMenu
withFrame
menu={item.menu}
openAt={item.openAt}
level={item.level}
animationClass={
this.state.menus_manager.willClose || item.willClose
? 'fade_out'
: item.level === 0 || item.positionType
? item.positionType === 'bottom'
? 'skew_in_bottom_nobounce'
: item.left
? 'skew_in_left_nobounce'
: 'skew_in_right_nobounce'
: 'fade_in'
}
testClassId={item.menuTestClassId}
/>
) : (
<MenuComponent
withFrame
menu={item.menu}
openAt={item.openAt}
level={item.level}
animationClass={
this.state.menus_manager.willClose || item.willClose
? 'fade_out'
: item.level === 0 || item.positionType
? item.positionType === 'bottom'
? 'skew_in_bottom_nobounce'
: item.left
? 'skew_in_left_nobounce'
: 'skew_in_right_nobounce'
: 'fade_in'
}
testClassId={item.menuTestClassId}
/>
)}
</div>
</OutsideClickHandler>
);
Expand Down
3 changes: 2 additions & 1 deletion tdrive/frontend/src/app/components/menus/menus-manager.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class MenusManager extends Observable {

this.notify();
}
async openMenu(menu, domRect, positionType, options, menuTestClassId) {
async openMenu(menu, domRect, positionType, options, menuTestClassId, enableMobileMenu) {
this.isOpen = 1;
if(typeof menu === 'function') {
menu = await menu();
Expand Down Expand Up @@ -86,6 +86,7 @@ class MenusManager extends Observable {
id: Number.unid(),
allowClickOut: options.allowClickOut !== undefined ? options.allowClickOut : true,
menuTestClassId,
enableMobileMenu,
});
this.last_opened_id = Number.unid();
this.notify();
Expand Down
161 changes: 161 additions & 0 deletions tdrive/frontend/src/app/components/menus/mobile-menu.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import React, { Component } from 'react';

import Icon from '@components/icon/icon.jsx';
import { Modal, ModalContent } from '@atoms/modal';
import Emojione from 'components/emojione/emojione';
import MenusManager from '@components/menus/menus-manager.jsx';
import './menu.scss';

/*
One menu
*/
export default class MobileMenu extends React.Component {
constructor(props) {
super();
this.state = {
menus_manager: MenusManager,
};
MenusManager.addListener(this);
}
componentWillUnmount() {
MenusManager.removeListener(this);
}
openSubMenu(dom_element, menu, level) {
var elementRect = window.getBoundingClientRect(dom_element);
elementRect.x = elementRect.x || elementRect.left;
elementRect.y = elementRect.y || elementRect.top;
MenusManager.openSubMenu(menu, elementRect, level);
}
closeSubMenu(level) {
MenusManager.closeSubMenu(level);
}
hoverMenu(dom_element, item) {
if (item.submenu && !item.submenu_replace) {
this.last_hovered = item;
this.openSubMenu(dom_element, item.submenu, this.props.level || 0);
} else {
this.closeSubMenu(this.props.level || 0);
}
}
clickMenu(dom_element, item, evt) {
if(Date.now() - this.props.openAt < 200 ){
// When a menu is open and another one opens above it, you have to block the buttons for a while. Otherwise, the hovered option of the new menu will be clicked
return;
}
if (item.submenu_replace) {
this.state.menus_manager.openMenu(item.submenu, { x: evt.clientX, y: evt.clientY }, 'center');
return;
}
if (item.onClick) {
var res = item.onClick(evt);
if (res !== false) {
this.state.menus_manager.closeMenu();
}
}
}
render() {
return (
<Modal
open={this.state.menus_manager.isOpen === 1}
closable={true}
onClose={() => this.state.menus_manager.closeMenu()}
className={`md:!max-w-sm testid:${this.props.testClassId}`}
disableCountVisibleModals={true}
>
<ModalContent title="">
<div
ref={node => (this.original_menu = node)}
className={
'menu-list sm:py-0 ' + (this.props.withFrame ? 'text-black bg-white dark:bg-zinc-900 dark:text-white rounded-lg ' : '') + this.props.animationClass
}>
{(this.props.menu || [])
.filter(item => item && !item.hide)
.map((item, index) => {
if (item.type == 'separator') {
return <div key={'menu_' + index} className="menu-separator" />;
} else if (item.type == 'title') {
return (
<div key={'menu_' + index} className={'menu-title ' + item.className}>
{item.text}
</div>
);
} else if (item.type == 'text') {
return (
<div
key={'menu_' + index}
ref={node => (item.ref = node)}
className={'menu-text ' + item.className + ' testid:menu-item'}
onMouseEnter={evt => {
this.hoverMenu(item.ref, item);
}}
>
{item.icon && (
<div className="icon">
{typeof item.icon === 'string' ? <Icon type={item.icon} /> : item.icon}
</div>
)}
<div className={`text testid:menu-item-${item.testClassId}`}>{item.text}</div>
</div>
);
} else if (item.type == 'react-element') {
return (
<div
key={'menu_' + index}
className={'menu-custom ' + item.className + ' testid:menu-item'}
onClick={item.onClick}
>
{typeof item.reactElement == 'function'
? item.reactElement(this.props.level)
: item.reactElement}
</div>
);
} else {
return (
<div
key={'menu_' + index}
ref={node => (item.ref = node)}
className={
'menu ' +
item.className +
' ' +
(this.state.menus_manager.max_level > this.props.level &&
this.last_hovered == item
? 'hovered '
: '') +
(item.selected ? 'selected ' : '') +
' testid:menu-item'
}
onMouseEnter={evt => {
this.hoverMenu(item.ref, item);
}}
onClick={evt => {
this.clickMenu(item.ref, item, evt);
}}
>
{item.icon && (
<div className="icon">
{typeof item.icon === 'string' ? <Icon type={item.icon} /> : item.icon}
</div>
)}
{item.emoji && (
<div className="icon">
<Emojione type={item.emoji} />
</div>
)}
<div className={`text testid:menu-item-${item.testClassId}`}>{item.text}</div>
<div className="more">
{item.rightIcon && <Icon type={item.rightIcon} />}
{item.submenu && !item.submenu_replace && <Icon type="angle-right" />}
</div>
</div>
);
}
})
}
</div>

</ModalContent>
</Modal>
);
}
}
14 changes: 8 additions & 6 deletions tdrive/frontend/src/app/views/client/body/drive/browser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,8 @@ export default memo(
key: index,
className:
(index === 0 ? 'rounded-t-md ' : '-mt-px ') +
(index === items.length - 1 ? 'rounded-b-md ' : ''),
(index === items.length - 1 ? 'rounded-b-md ' : '') +
'border-0 md:border',
item: child,
checked: checked[child.id] || false,
onCheck: (v: boolean) => setChecked(_.pickBy({ ...checked, [child.id]: v }, _.identity)),
Expand Down Expand Up @@ -358,7 +359,7 @@ export default memo(
(loading && (!items?.length || loadingParentChange) ? 'opacity-50 ' : '')
}
>
<div className={`flex flex-row shrink-0 items-center mb-4 ${!sharedWithMe ? 'flex-wrap' : ''}`}>
<div className={`flex flex-row shrink-0 items-center mb-4 ${!sharedWithMe ? 'flex-wrap' : ''} border-b md:border-b-0 px-4 py-2 md:px-0 md:py-0`}>
{sharedWithMe ? (
<div>
<Title className="mb-4 block">
Expand Down Expand Up @@ -445,14 +446,14 @@ export default memo(
<div className="grow" />

{access !== 'read' && (
<BaseSmall>
<BaseSmall className="hidden md:block">
{formatBytes(item?.size || 0)} {Languages.t('scenes.app.drive.used')}
</BaseSmall>
)}

<Menu menu={() => onBuildSortContextMenu()} sortData={sortLabel} testClassId="browser-menu-sorting">
{' '}
<Button theme="outline" className="ml-4 flex flex-row items-center" testClassId="button-sorting">
<Button theme="outline" className="ml-4 flex flex-row items-center border-0 md:border !text-gray-500 md:!text-blue-500 px-0 md:px-4" testClassId="button-sorting">
<SortIcon
className={`h-4 w-4 mr-2 -ml-1 ${
sortLabel.order === 'asc' ? 'transform rotate-180' : ''
Expand All @@ -467,7 +468,7 @@ export default memo(
{viewId !== 'shared_with_me' && (
<Menu menu={() => onBuildContextMenu(details)} testClassId="browser-menu-more">
{' '}
<Button theme="secondary" className="ml-4 flex flex-row items-center" testClassId="button-more">
<Button theme="secondary" className="ml-4 flex flex-row items-center bg-transparent md:bg-blue-500 md:bg-opacity-25 !text-gray-500 md:!text-blue-500 px-0 md:px-4" testClassId="button-more">
<span>
{selectedCount > 1
? `${selectedCount} items`
Expand Down Expand Up @@ -510,7 +511,8 @@ export default memo(
key={index}
className={
(index === 0 ? 'rounded-t-md ' : '-mt-px ') +
(index === items.length - 1 ? 'rounded-b-md ' : '')
(index === items.length - 1 ? 'rounded-b-md ' : '') +
'border-0 md:border'
}
item={child}
onClick={() => {
Expand Down
Loading

0 comments on commit f87d85a

Please sign in to comment.