mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-09 18:44:16 +00:00
update ui & bad typos
This commit is contained in:
parent
e28efd1698
commit
1170d0d858
@ -59,7 +59,7 @@ export default {
|
||||
icon: "Moon",
|
||||
title: "Sync with system",
|
||||
description: "Automatically switch to dark mode based on your system preference.",
|
||||
emitEvent: "style.autoDarkModeToogle",
|
||||
emitEvent: "style.autoDarkModetoggle",
|
||||
storaged: true,
|
||||
},
|
||||
{
|
||||
|
@ -124,7 +124,11 @@ const ChangePasswordComponent = (props) => {
|
||||
|
||||
export default (props) => {
|
||||
const onClick = () => {
|
||||
app.SidedrawerController.open("passwordChange", ChangePasswordComponent)
|
||||
if (app.isMobile) {
|
||||
return app.DrawerController.open("passwordChange", ChangePasswordComponent)
|
||||
}
|
||||
|
||||
return app.layout.sidedrawer.open("passwordChange", ChangePasswordComponent)
|
||||
}
|
||||
|
||||
return <antd.Button onClick={onClick}>
|
||||
|
@ -32,7 +32,7 @@ export default class WidgetsView extends React.Component {
|
||||
})
|
||||
}}
|
||||
onChangeVisible={(visible) => {
|
||||
app.cores.widgets.toogleVisibility(manifest._id, visible)
|
||||
app.cores.widgets.toggleVisibility(manifest._id, visible)
|
||||
}}
|
||||
/>
|
||||
</React.Fragment>
|
||||
|
@ -157,6 +157,23 @@ class ComtyApp extends React.Component {
|
||||
|
||||
static publicMethods = {
|
||||
controls: {
|
||||
toogleUIVisibility: (to) => {
|
||||
if (app.layout.sidebar) {
|
||||
app.layout.sidebar.toggleVisibility(to)
|
||||
}
|
||||
|
||||
if (app.layout.tools_bar) {
|
||||
app.layout.tools_bar.toggleVisibility(to)
|
||||
}
|
||||
|
||||
if (app.layout.top_bar) {
|
||||
app.layout.top_bar.toggleVisibility(to)
|
||||
}
|
||||
|
||||
if (app.layout.floatingStack) {
|
||||
app.layout.floatingStack.toggleGlobalVisibility(to)
|
||||
}
|
||||
},
|
||||
openLoginForm: async (options = {}) => {
|
||||
app.DrawerController.open("login", Login, {
|
||||
defaultLocked: options.defaultLocked ?? false,
|
||||
@ -178,7 +195,7 @@ class ComtyApp extends React.Component {
|
||||
},
|
||||
// Opens the notification window and sets up the UI for the notification to be displayed
|
||||
openNotifications: () => {
|
||||
window.app.SidedrawerController.open("notifications", NotificationsCenter, {
|
||||
window.app.layout.sidedrawer.open("notifications", NotificationsCenter, {
|
||||
props: {
|
||||
width: "fit-content",
|
||||
},
|
||||
|
@ -51,7 +51,7 @@ export default class FormGenerator extends React.Component {
|
||||
},
|
||||
clearForm: () => {
|
||||
this.ctx.clearErrors()
|
||||
this.ctx.toogleValidation(false)
|
||||
this.ctx.toggleValidation(false)
|
||||
this.ref.current.resetFields()
|
||||
},
|
||||
finish: () => this.ref.current.submit(),
|
||||
@ -61,7 +61,7 @@ export default class FormGenerator extends React.Component {
|
||||
shake: (id) => {
|
||||
this.formItemShake(id)
|
||||
},
|
||||
toogleValidation: (to) => {
|
||||
toggleValidation: (to) => {
|
||||
if (typeof to !== "undefined") {
|
||||
return this.setState({ validating: to })
|
||||
}
|
||||
|
@ -15,6 +15,19 @@ import CreatorView from "pages/@mobile-views/creator"
|
||||
|
||||
import "./index.less"
|
||||
|
||||
const tourSteps = [
|
||||
{
|
||||
title: "Open quick nav",
|
||||
description: "Xd",
|
||||
ref: React.createRef(),
|
||||
},
|
||||
{
|
||||
title: "Account button",
|
||||
description: "Xd",
|
||||
ref: React.createRef(),
|
||||
}
|
||||
]
|
||||
|
||||
const openPlayerView = () => {
|
||||
app.DrawerController.open("player", PlayerView)
|
||||
}
|
||||
@ -53,7 +66,7 @@ const PlayerButton = (props) => {
|
||||
</div>
|
||||
}
|
||||
|
||||
const AccountButton = (props) => {
|
||||
const AccountButton = React.forwardRef((props, ref) => {
|
||||
const user = app.userData
|
||||
const ActionSheetRef = React.useRef()
|
||||
|
||||
@ -101,6 +114,7 @@ const AccountButton = (props) => {
|
||||
key="account"
|
||||
id="account"
|
||||
className="item"
|
||||
ref={ref}
|
||||
onClick={handleClick}
|
||||
onContextMenu={handleHold}
|
||||
context-menu="ignore"
|
||||
@ -111,7 +125,7 @@ const AccountButton = (props) => {
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
})
|
||||
|
||||
export default (props) => {
|
||||
return <WithPlayerContext>
|
||||
@ -128,6 +142,7 @@ export class BottomBar extends React.Component {
|
||||
visible: false,
|
||||
quickNavVisible: false,
|
||||
render: null,
|
||||
tourOpen: false,
|
||||
}
|
||||
|
||||
busEvents = {
|
||||
@ -136,9 +151,14 @@ export class BottomBar extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
refs = {
|
||||
homeBtn: React.createRef(),
|
||||
accountBtn: React.createRef(),
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
this.interface = app.layout.bottom_bar = {
|
||||
toogleVisible: this.toggleVisibility,
|
||||
toggleVisible: this.toggleVisibility,
|
||||
isVisible: () => this.state.visible,
|
||||
render: (fragment) => {
|
||||
this.setState({ render: fragment })
|
||||
@ -146,6 +166,9 @@ export class BottomBar extends React.Component {
|
||||
clear: () => {
|
||||
this.setState({ render: null })
|
||||
},
|
||||
toggleTour: () => {
|
||||
this.setState({ tourOpen: !this.state.tourOpen })
|
||||
},
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
@ -278,6 +301,16 @@ export class BottomBar extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
toggleTour = (to) => {
|
||||
if (typeof to === "undefined") {
|
||||
to = !this.state.tourOpen
|
||||
}
|
||||
|
||||
this.setState({
|
||||
tourOpen: to
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.render) {
|
||||
return <div className="bottomBar">
|
||||
@ -358,7 +391,7 @@ export class BottomBar extends React.Component {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<AccountButton />
|
||||
<AccountButton/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -195,8 +195,8 @@
|
||||
.icon {
|
||||
border-radius: 360px;
|
||||
|
||||
height: @app_bottomBar_iconSize;
|
||||
width: @app_bottomBar_iconSize;
|
||||
height: @bottomBar_iconSize;
|
||||
width: @bottomBar_iconSize;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
@ -120,7 +120,7 @@ export class Drawer extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
toogleVisibility = (to) => {
|
||||
toggleVisibility = (to) => {
|
||||
this.setState({ visible: to ?? !this.state.visible })
|
||||
}
|
||||
|
||||
@ -137,7 +137,7 @@ export class Drawer extends React.Component {
|
||||
return console.warn("Cannot close a locked drawer")
|
||||
}
|
||||
|
||||
this.toogleVisibility(false)
|
||||
this.toggleVisibility(false)
|
||||
|
||||
this.events.emit("beforeClose")
|
||||
|
||||
|
@ -4,4 +4,5 @@ export { default as Drawer } from "./drawer"
|
||||
export { default as Sidebar } from "./sidebar"
|
||||
export { default as Sidedrawer } from "./sidedrawer"
|
||||
export { default as Modal } from "./modal"
|
||||
export { default as Header } from "./header"
|
||||
export { default as Header } from "./header"
|
||||
export { default as ToolsBar } from "./toolsBar"
|
@ -90,6 +90,9 @@ export default class Sidebar extends React.Component {
|
||||
|
||||
topItems: generateTopItems(),
|
||||
bottomItems: [],
|
||||
|
||||
lockAutocollapse: false,
|
||||
navigationRender: null,
|
||||
}
|
||||
|
||||
sidebarRef = React.createRef()
|
||||
@ -97,10 +100,49 @@ export default class Sidebar extends React.Component {
|
||||
collapseDebounce = null
|
||||
|
||||
interface = window.app.layout.sidebar = {
|
||||
toggleVisibility: this.toggleVisibility,
|
||||
toggleCollapse: this.toggleExpanded,
|
||||
toggleVisibility: (to) => {
|
||||
this.setState({ visible: to ?? !this.state.visible })
|
||||
},
|
||||
toggleCollapse: (to, force) => {
|
||||
to = to ?? !this.state.expanded
|
||||
|
||||
if (this.collapseDebounce) {
|
||||
clearTimeout(this.collapseDebounce)
|
||||
this.collapseDebounce = null
|
||||
}
|
||||
|
||||
if (!to & this.state.dropdownOpen && !force) {
|
||||
// FIXME: This is a walkaround for a bug in antd, causing when dropdown set to close, item click event is not fired
|
||||
// The desing defines when sidebar should be collapsed, dropdown should be closed, but in this case, gonna to keep it open untils dropdown is closed
|
||||
//this.setState({ dropdownOpen: false })
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
if (!to) {
|
||||
if (this.state.lockAutocollapse) {
|
||||
return false
|
||||
}
|
||||
|
||||
this.collapseDebounce = setTimeout(() => {
|
||||
this.setState({ expanded: to })
|
||||
}, window.app.cores.settings.get("sidebar.collapse_delay_time") ?? 500)
|
||||
} else {
|
||||
this.setState({ expanded: to })
|
||||
}
|
||||
|
||||
app.eventBus.emit("sidebar.expanded", to)
|
||||
},
|
||||
isVisible: () => this.state.visible,
|
||||
isExpanded: () => this.state.expanded,
|
||||
renderNavigationBar: (component, options) => {
|
||||
this.setState({
|
||||
navigationRender: {
|
||||
component,
|
||||
options,
|
||||
}
|
||||
})
|
||||
},
|
||||
updateBottomItemProps: (id, newProps) => {
|
||||
let updatedValue = this.state.bottomItems
|
||||
|
||||
@ -153,17 +195,37 @@ export default class Sidebar extends React.Component {
|
||||
},
|
||||
}
|
||||
|
||||
events = {
|
||||
"sidedrawers.visible": (has) => {
|
||||
this.setState({
|
||||
lockAutocollapse: has
|
||||
})
|
||||
|
||||
if (!has && this.state.expanded) {
|
||||
this.interface.toggleCollapse(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount = async () => {
|
||||
for (const [event, handler] of Object.entries(this.events)) {
|
||||
app.eventBus.on(event, handler)
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
this.toggleVisibility(true)
|
||||
this.interface.toggleVisibility(true)
|
||||
|
||||
if (app.cores.settings.is("sidebar.collapsable", false)) {
|
||||
this.toggleExpanded(true)
|
||||
this.interface.toggleCollapse(true)
|
||||
}
|
||||
}, 10)
|
||||
}
|
||||
|
||||
componentWillUnmount = () => {
|
||||
for (const [event, handler] of Object.entries(this.events)) {
|
||||
app.eventBus.off(event, handler)
|
||||
}
|
||||
|
||||
delete app.layout.sidebar
|
||||
}
|
||||
|
||||
@ -192,49 +254,18 @@ export default class Sidebar extends React.Component {
|
||||
return window.app.location.push(`/${item.path ?? e.key}`, 150)
|
||||
}
|
||||
|
||||
toggleExpanded = (to, force) => {
|
||||
to = to ?? !this.state.expanded
|
||||
|
||||
if (this.collapseDebounce) {
|
||||
clearTimeout(this.collapseDebounce)
|
||||
this.collapseDebounce = null
|
||||
}
|
||||
|
||||
if (!to & this.state.dropdownOpen && !force) {
|
||||
// FIXME: This is a walkaround for a bug in antd, causing when dropdown set to close, item click event is not fired
|
||||
// The desing defines when sidebar should be collapsed, dropdown should be closed, but in this case, gonna to keep it open untils dropdown is closed
|
||||
//this.setState({ dropdownOpen: false })
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
if (!to) {
|
||||
this.collapseDebounce = setTimeout(() => {
|
||||
this.setState({ expanded: to })
|
||||
}, window.app.cores.settings.get("sidebar.collapse_delay_time") ?? 500)
|
||||
} else {
|
||||
this.setState({ expanded: to })
|
||||
}
|
||||
|
||||
app.eventBus.emit("sidebar.expanded", to)
|
||||
}
|
||||
|
||||
toggleVisibility = (to) => {
|
||||
this.setState({ visible: to ?? !this.state.visible })
|
||||
}
|
||||
|
||||
onMouseEnter = () => {
|
||||
if (!this.state.visible) return
|
||||
|
||||
if (window.app.cores.settings.is("sidebar.collapsable", false)) {
|
||||
if (!this.state.expanded) {
|
||||
this.toggleExpanded(true)
|
||||
this.interface.toggleCollapse(true)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
this.toggleExpanded(true)
|
||||
this.interface.toggleCollapse(true)
|
||||
}
|
||||
|
||||
handleMouseLeave = () => {
|
||||
@ -242,13 +273,13 @@ export default class Sidebar extends React.Component {
|
||||
|
||||
if (window.app.cores.settings.is("sidebar.collapsable", false)) return
|
||||
|
||||
this.toggleExpanded(false)
|
||||
this.interface.toggleCollapse(false)
|
||||
}
|
||||
|
||||
onDropdownOpenChange = (to) => {
|
||||
// this is another walkaround for a bug in antd, causing when dropdown set to close, item click event is not fired
|
||||
if (!to && this.state.expanded) {
|
||||
this.toggleExpanded(false, true)
|
||||
this.interface.toggleCollapse(false, true)
|
||||
}
|
||||
|
||||
this.setState({ dropdownOpen: to })
|
||||
@ -265,126 +296,133 @@ export default class Sidebar extends React.Component {
|
||||
render() {
|
||||
const defaultSelectedKey = window.location.pathname.replace("/", "")
|
||||
|
||||
return <Motion style={{
|
||||
x: spring(!this.state.visible ? 100 : 0),
|
||||
}}>
|
||||
{({ x }) => {
|
||||
return <div
|
||||
className="app_sidebar_wrapper"
|
||||
style={{
|
||||
transform: `translateX(-${x}%)`,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
onMouseEnter={this.onMouseEnter}
|
||||
onMouseLeave={this.handleMouseLeave}
|
||||
return <>
|
||||
<Motion style={{
|
||||
x: spring(!this.state.visible ? 100 : 0),
|
||||
}}>
|
||||
{({ x }) => {
|
||||
return <div
|
||||
className={classnames(
|
||||
"app_sidebar",
|
||||
"app_sidebar_wrapper",
|
||||
{
|
||||
["expanded"]: this.state.visible && this.state.expanded,
|
||||
["hidden"]: !this.state.visible,
|
||||
visible: this.state.visible,
|
||||
}
|
||||
)
|
||||
}
|
||||
ref={this.sidebarRef}
|
||||
)}
|
||||
style={{
|
||||
transform: `translateX(-${x}%)`,
|
||||
}}
|
||||
>
|
||||
|
||||
<div className="app_sidebar_header">
|
||||
<div className="app_sidebar_header_logo">
|
||||
<img src={config.logo?.alt} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div key="menu" className="app_sidebar_menu_wrapper">
|
||||
<Menu
|
||||
mode="inline"
|
||||
onClick={this.handleClick}
|
||||
defaultSelectedKeys={[defaultSelectedKey]}
|
||||
items={this.state.topItems}
|
||||
selectable
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
key="bottom"
|
||||
onMouseEnter={this.onMouseEnter}
|
||||
onMouseLeave={this.handleMouseLeave}
|
||||
className={classnames(
|
||||
"app_sidebar_menu_wrapper",
|
||||
"bottom"
|
||||
)}
|
||||
"app_sidebar",
|
||||
{
|
||||
["expanded"]: this.state.visible && this.state.expanded,
|
||||
["hidden"]: !this.state.visible,
|
||||
}
|
||||
)
|
||||
}
|
||||
ref={this.sidebarRef}
|
||||
>
|
||||
<Menu
|
||||
selectable={false}
|
||||
mode="inline"
|
||||
onClick={this.handleClick}
|
||||
|
||||
<div className="app_sidebar_header">
|
||||
<div className="app_sidebar_header_logo">
|
||||
<img src={config.logo?.alt} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div key="menu" className="app_sidebar_menu_wrapper">
|
||||
<Menu
|
||||
mode="inline"
|
||||
onClick={this.handleClick}
|
||||
defaultSelectedKeys={[defaultSelectedKey]}
|
||||
items={this.state.topItems}
|
||||
selectable
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
key="bottom"
|
||||
className={classnames(
|
||||
"app_sidebar_menu_wrapper",
|
||||
"bottom"
|
||||
)}
|
||||
>
|
||||
{
|
||||
this.state.bottomItems.map((item) => {
|
||||
if (item.noContainer) {
|
||||
return React.createElement(item.children, item.childrenProps)
|
||||
}
|
||||
|
||||
return <Menu.Item
|
||||
key={item.id}
|
||||
className="extra_bottom_item"
|
||||
icon={createIconRender(item.icon)}
|
||||
disabled={item.disabled ?? false}
|
||||
{...item.containerProps}
|
||||
>
|
||||
{
|
||||
React.createElement(item.children, item.childrenProps)
|
||||
<Menu
|
||||
selectable={false}
|
||||
mode="inline"
|
||||
onClick={this.handleClick}
|
||||
>
|
||||
{
|
||||
this.state.bottomItems.map((item) => {
|
||||
if (item.noContainer) {
|
||||
return React.createElement(item.children, item.childrenProps)
|
||||
}
|
||||
</Menu.Item>
|
||||
})
|
||||
}
|
||||
<Menu.Item key="search" icon={<Icons.Search />} >
|
||||
<Translation>
|
||||
{(t) => t("Search")}
|
||||
</Translation>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="notifications" icon={<Icons.Bell />}>
|
||||
<Translation>
|
||||
{t => t("Notifications")}
|
||||
</Translation>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="settings" icon={<Icons.Settings />}>
|
||||
<Translation>
|
||||
{t => t("Settings")}
|
||||
</Translation>
|
||||
</Menu.Item>
|
||||
|
||||
{
|
||||
app.userData && <Dropdown
|
||||
menu={{
|
||||
items: ActionMenuItems,
|
||||
onClick: this.onClickDropdownItem
|
||||
}}
|
||||
autoFocus
|
||||
placement="top"
|
||||
trigger={["click"]}
|
||||
onOpenChange={this.onDropdownOpenChange}
|
||||
>
|
||||
<Menu.Item
|
||||
key="account"
|
||||
className="user_avatar"
|
||||
ignoreClick
|
||||
>
|
||||
<Avatar shape="square" src={app.userData?.avatar} />
|
||||
</Menu.Item>
|
||||
</Dropdown>
|
||||
}
|
||||
|
||||
{
|
||||
!app.userData && <Menu.Item key="login" icon={<Icons.LogIn />}>
|
||||
return <Menu.Item
|
||||
key={item.id}
|
||||
className="extra_bottom_item"
|
||||
icon={createIconRender(item.icon)}
|
||||
disabled={item.disabled ?? false}
|
||||
{...item.containerProps}
|
||||
>
|
||||
{
|
||||
React.createElement(item.children, item.childrenProps)
|
||||
}
|
||||
</Menu.Item>
|
||||
})
|
||||
}
|
||||
<Menu.Item key="search" icon={<Icons.Search />} >
|
||||
<Translation>
|
||||
{t => t("Login")}
|
||||
{(t) => t("Search")}
|
||||
</Translation>
|
||||
</Menu.Item>
|
||||
}
|
||||
</Menu>
|
||||
<Menu.Item key="notifications" icon={<Icons.Bell />}>
|
||||
<Translation>
|
||||
{t => t("Notifications")}
|
||||
</Translation>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="settings" icon={<Icons.Settings />}>
|
||||
<Translation>
|
||||
{t => t("Settings")}
|
||||
</Translation>
|
||||
</Menu.Item>
|
||||
|
||||
{
|
||||
app.userData && <Dropdown
|
||||
menu={{
|
||||
items: ActionMenuItems,
|
||||
onClick: this.onClickDropdownItem
|
||||
}}
|
||||
autoFocus
|
||||
placement="top"
|
||||
trigger={["click"]}
|
||||
onOpenChange={this.onDropdownOpenChange}
|
||||
>
|
||||
<Menu.Item
|
||||
key="account"
|
||||
className="user_avatar"
|
||||
ignoreClick
|
||||
>
|
||||
<Avatar shape="square" src={app.userData?.avatar} />
|
||||
</Menu.Item>
|
||||
</Dropdown>
|
||||
}
|
||||
|
||||
{
|
||||
!app.userData && <Menu.Item key="login" icon={<Icons.LogIn />}>
|
||||
<Translation>
|
||||
{t => t("Login")}
|
||||
</Translation>
|
||||
</Menu.Item>
|
||||
}
|
||||
</Menu>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}}
|
||||
</Motion>
|
||||
}}
|
||||
</Motion>
|
||||
</>
|
||||
}
|
||||
}
|
@ -8,12 +8,21 @@
|
||||
|
||||
z-index: 1000;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
align-items: center;
|
||||
|
||||
gap: 20px;
|
||||
|
||||
width: fit-content;
|
||||
|
||||
height: 100vh;
|
||||
height: 100dvh;
|
||||
|
||||
padding: 10px;
|
||||
&.visible {
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.app_sidebar {
|
||||
|
@ -1,62 +1,79 @@
|
||||
import React from "react"
|
||||
import classnames from "classnames"
|
||||
import { Motion, spring } from "react-motion"
|
||||
|
||||
import "./index.less"
|
||||
|
||||
export const Sidedrawer = (props) => {
|
||||
const sidedrawerId = props.id ?? props.key
|
||||
export class Sidedrawer extends React.Component {
|
||||
state = {
|
||||
visible: false,
|
||||
}
|
||||
|
||||
return <div
|
||||
key={sidedrawerId}
|
||||
id={sidedrawerId}
|
||||
style={props.style}
|
||||
className={
|
||||
classnames("sidedrawer", {
|
||||
"hided": !props.defaultVisible,
|
||||
"first": props.first
|
||||
})
|
||||
}
|
||||
>
|
||||
{
|
||||
React.createElement(props.children, {
|
||||
...props.props,
|
||||
close: props.close,
|
||||
})
|
||||
}
|
||||
</div>
|
||||
toggleVisibility = (to) => {
|
||||
this.setState({ visible: to ?? !this.state.visible })
|
||||
}
|
||||
|
||||
render() {
|
||||
return <Motion style={{
|
||||
x: spring(!this.state.visible ? 100 : 0),
|
||||
opacity: spring(!this.state.visible ? 0 : 1),
|
||||
}}>
|
||||
{({ x, opacity }) => {
|
||||
return <div
|
||||
key={this.props.id}
|
||||
id={this.props.id}
|
||||
className={classnames(
|
||||
"sidedrawer",
|
||||
{
|
||||
"first": this.props.first
|
||||
}
|
||||
)}
|
||||
style={{
|
||||
...this.props.style,
|
||||
transform: `translateX(-${x}%)`,
|
||||
opacity: opacity,
|
||||
}}
|
||||
|
||||
>
|
||||
{
|
||||
React.createElement(this.props.children, {
|
||||
...this.props.props,
|
||||
close: this.props.close,
|
||||
})
|
||||
}
|
||||
</div>
|
||||
}}
|
||||
</Motion>
|
||||
}
|
||||
}
|
||||
|
||||
export default class SidedrawerController extends React.Component {
|
||||
state = {
|
||||
drawers: [],
|
||||
lockedIds: [],
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
this.controller = window.app["SidedrawerController"] = {
|
||||
this.interface = app.layout.sidedrawer = {
|
||||
open: this.open,
|
||||
close: this.close,
|
||||
closeAll: this.closeAll,
|
||||
hasDrawers: this.state.drawers.length > 0,
|
||||
toggleGlobalVisibility: () => {
|
||||
this.setState({
|
||||
globalVisible: !this.state.globalVisible,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state = {
|
||||
globalVisible: true,
|
||||
drawers: [],
|
||||
lockedIds: [],
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
this.listenEscape()
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.controller.hasDrawers = this.state.drawers.length > 0
|
||||
|
||||
if (this.controller.hasDrawers) {
|
||||
window.app.eventBus.emit("sidedrawer.hasDrawers")
|
||||
} else {
|
||||
window.app.eventBus.emit("sidedrawer.noDrawers")
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount = () => {
|
||||
this.unlistenEscape()
|
||||
}
|
||||
@ -84,7 +101,7 @@ export default class SidedrawerController extends React.Component {
|
||||
id = component.key ?? component.id ?? Math.random().toString(36).substr(2, 9)
|
||||
}
|
||||
|
||||
let drawers = this.state.drawers
|
||||
const drawers = this.state.drawers
|
||||
|
||||
// check if id is already in use
|
||||
// but only if its allowed to be used multiple times
|
||||
@ -111,56 +128,56 @@ export default class SidedrawerController extends React.Component {
|
||||
id = newId
|
||||
}
|
||||
|
||||
drawers.push(React.createElement(
|
||||
Sidedrawer,
|
||||
{
|
||||
key: id,
|
||||
id: id,
|
||||
first: drawers.length === 0,
|
||||
style: {
|
||||
zIndex: 100 - drawers.length,
|
||||
},
|
||||
allowMultiples: options.allowMultiples ?? false,
|
||||
...options.props,
|
||||
close: this.close,
|
||||
escClosable: options.escClosable ?? true,
|
||||
defaultVisible: false,
|
||||
selfLock: () => {
|
||||
this.lockDrawerId(id)
|
||||
},
|
||||
selfUnlock: () => {
|
||||
this.unlockDrawer(id)
|
||||
}
|
||||
const drawerProps = {
|
||||
id: id,
|
||||
allowMultiples: options.allowMultiples ?? false,
|
||||
escClosable: options.escClosable ?? true,
|
||||
first: drawers.length === 0,
|
||||
style: {
|
||||
zIndex: 100 - drawers.length,
|
||||
},
|
||||
component
|
||||
))
|
||||
ref: React.createRef(),
|
||||
close: this.close,
|
||||
lock: () => this.lockDrawerId(id),
|
||||
unlock: () => this.unlockDrawer(id),
|
||||
}
|
||||
|
||||
drawers.push(React.createElement(Sidedrawer, drawerProps, component))
|
||||
|
||||
if (options.lock) {
|
||||
this.lockDrawerId(id)
|
||||
}
|
||||
|
||||
await this.setState({ drawers })
|
||||
await this.setState({
|
||||
drawers,
|
||||
})
|
||||
|
||||
setTimeout(() => {
|
||||
this.toggleDrawerVisibility(id, true)
|
||||
}, 10)
|
||||
|
||||
window.app.eventBus.emit("sidedrawer.open")
|
||||
|
||||
if (this.state.drawers.length > 0) {
|
||||
app.eventBus.emit("sidedrawers.visible", true)
|
||||
}
|
||||
}
|
||||
|
||||
toggleDrawerVisibility = (id, to) => {
|
||||
const drawer = document.getElementById(id)
|
||||
const drawerClasses = drawer.classList
|
||||
// find drawer
|
||||
const drawer = this.state.drawers.find(drawer => drawer.props.id === id)
|
||||
|
||||
if (to) {
|
||||
app.cores.sound.useUIAudio("sidebar.expand")
|
||||
|
||||
drawerClasses.remove("hided")
|
||||
} else {
|
||||
app.cores.sound.useUIAudio("sidebar.collapse")
|
||||
|
||||
drawerClasses.add("hided")
|
||||
if (!drawer) {
|
||||
console.warn(`Sidedrawer with id "${id}" does not exist.`)
|
||||
return
|
||||
}
|
||||
|
||||
if (!drawer.ref.current) {
|
||||
console.warn(`Sidedrawer with id "${id}" has not valid ref.`)
|
||||
return
|
||||
}
|
||||
|
||||
return drawer.ref.current.toggleVisibility(to)
|
||||
}
|
||||
|
||||
close = (id) => {
|
||||
@ -186,7 +203,7 @@ export default class SidedrawerController extends React.Component {
|
||||
// emit event
|
||||
window.app.eventBus.emit("sidedrawer.close")
|
||||
|
||||
// toogleVisibility off
|
||||
// toggleVisibility off
|
||||
this.toggleDrawerVisibility(drawerId, false)
|
||||
|
||||
// await drawer transition
|
||||
@ -195,6 +212,10 @@ export default class SidedrawerController extends React.Component {
|
||||
drawers = drawers.filter(drawer => drawer.props.id !== drawerId)
|
||||
|
||||
this.setState({ drawers })
|
||||
|
||||
if (this.state.drawers.length === 0) {
|
||||
app.eventBus.emit("sidedrawers.visible", false)
|
||||
}
|
||||
}, 500)
|
||||
}
|
||||
|
||||
@ -231,7 +252,7 @@ export default class SidedrawerController extends React.Component {
|
||||
className={classnames(
|
||||
"sidedrawers-wrapper",
|
||||
{
|
||||
["floating-sidebar"]: window.app?.cores.settings.get("sidebar.floating")
|
||||
["hidden"]: !this.state.drawers.length || this.state.globalVisible,
|
||||
}
|
||||
)}
|
||||
>
|
||||
|
@ -1,50 +1,48 @@
|
||||
@import "theme/vars.less";
|
||||
|
||||
.sidedrawers-wrapper {
|
||||
position: relative;
|
||||
top: 0;
|
||||
right: 0;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
&.floating-sidebar {
|
||||
z-index: 950;
|
||||
position: absolute;
|
||||
margin-left: @app_sidebar_width;
|
||||
}
|
||||
|
||||
.sidedrawer {
|
||||
position: relative;
|
||||
padding: @sidebar_padding;
|
||||
|
||||
width: auto; // by default
|
||||
height: 100vh;
|
||||
height: 100dvh;
|
||||
height: 100vh;
|
||||
|
||||
.sidedrawer {
|
||||
position: absolute;
|
||||
|
||||
z-index: 100;
|
||||
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
|
||||
margin-top: @sidebar_padding;
|
||||
height: calc(100% - @sidebar_padding * 2);
|
||||
|
||||
width: auto;
|
||||
|
||||
min-width: 400px;
|
||||
|
||||
z-index: 20;
|
||||
max-width: 15vw;
|
||||
|
||||
background-color: var(--sidedrawer-background-color);
|
||||
border-radius: 0 @app_sidebar_borderRadius @app_sidebar_borderRadius 0;
|
||||
border-radius: @sidebar_borderRadius;
|
||||
|
||||
padding: 20px;
|
||||
padding-left: 30px;
|
||||
|
||||
transform: translate(-20px, 0);
|
||||
|
||||
overflow-x: hidden;
|
||||
overflow-y: overlay;
|
||||
|
||||
word-break: break-all;
|
||||
transition: all 150ms ease-in-out;
|
||||
box-shadow: @card-shadow;
|
||||
}
|
||||
|
||||
// create shadow on the right side
|
||||
box-shadow: 0 0 5px 4px rgba(0, 0, 0, 0.1) !important;
|
||||
|
||||
&.first {
|
||||
transform: translate(-10px, 0);
|
||||
}
|
||||
|
||||
&.hided {
|
||||
width: 0;
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
}
|
||||
&.hidden{
|
||||
width: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
89
packages/app/src/components/Layout/toolsBar/index.jsx
Normal file
89
packages/app/src/components/Layout/toolsBar/index.jsx
Normal file
@ -0,0 +1,89 @@
|
||||
import React from "react"
|
||||
import * as antd from "antd"
|
||||
import classnames from "classnames"
|
||||
import { Motion, spring } from "react-motion"
|
||||
import { Translation } from "react-i18next"
|
||||
|
||||
import { Icons } from "components/Icons"
|
||||
|
||||
import { HashtagTrendings, FeaturedEventsAnnouncements, ConnectedFriends } from "components"
|
||||
import WidgetsWrapper from "components/WidgetsWrapper"
|
||||
|
||||
import "./index.less"
|
||||
|
||||
export default class ToolsBar extends React.Component {
|
||||
state = {
|
||||
visible: false,
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
app.layout.tools_bar = this.interface
|
||||
|
||||
setTimeout(() => {
|
||||
this.setState({
|
||||
visible: true,
|
||||
})
|
||||
}, 10)
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
delete app.layout.tools_bar
|
||||
}
|
||||
|
||||
interface = {
|
||||
toggleVisibility: (to) => {
|
||||
this.setState({
|
||||
visible: to ?? !this.state.visible,
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
render() {
|
||||
return <Motion style={{
|
||||
x: spring(this.state.visible ? 0 : 100),
|
||||
width: spring(this.state.visible ? 100 : 0),
|
||||
}}>
|
||||
{({ x, width }) => {
|
||||
return <div
|
||||
id="tools_bar"
|
||||
className={classnames(
|
||||
"tools-bar",
|
||||
{
|
||||
visible: this.state.visible,
|
||||
}
|
||||
)}
|
||||
style={{
|
||||
width: `${width}%`,
|
||||
transform: `translateX(${x}%)`,
|
||||
}}
|
||||
>
|
||||
<FeaturedEventsAnnouncements />
|
||||
|
||||
<div className="card" id="trendings">
|
||||
<div className="header">
|
||||
<h2>
|
||||
<Icons.TrendingUp />
|
||||
<Translation>{(t) => t("Trendings")}</Translation>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<HashtagTrendings />
|
||||
</div>
|
||||
|
||||
<div className="card" id="onlineFriends">
|
||||
<div className="header">
|
||||
<h2>
|
||||
<Icons.MdPeopleAlt />
|
||||
<Translation>{(t) => t("Online Friends")}</Translation>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<ConnectedFriends />
|
||||
</div>
|
||||
|
||||
<WidgetsWrapper />
|
||||
</div>
|
||||
}}
|
||||
</Motion>
|
||||
}
|
||||
}
|
67
packages/app/src/components/Layout/toolsBar/index.less
Normal file
67
packages/app/src/components/Layout/toolsBar/index.less
Normal file
@ -0,0 +1,67 @@
|
||||
.tools-bar {
|
||||
position: relative;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
max-width: 20vw;
|
||||
|
||||
height: 100vh;
|
||||
height: 100dvh;
|
||||
|
||||
border-left: 1px solid var(--border-color);
|
||||
|
||||
gap: 20px;
|
||||
|
||||
|
||||
&.visible {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
background-color: var(--background-color-accent);
|
||||
border-radius: 12px;
|
||||
|
||||
padding: 20px;
|
||||
|
||||
isolation: isolate;
|
||||
|
||||
h1,
|
||||
h2 {
|
||||
width: fit-content;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&.header {
|
||||
position: relative;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
width: 100%;
|
||||
|
||||
margin-bottom: 10px;
|
||||
|
||||
z-index: 50;
|
||||
|
||||
-webkit-box-shadow: 0 0 0 1px rgba(63, 63, 68, 0.05), 0 1px 3px 0 var(--shadow-color);
|
||||
-moz-box-shadow: 0 0 0 1px rgba(63, 63, 68, 0.05), 0 1px 3px 0 var(--shadow-color);
|
||||
box-shadow: 0 0 0 1px rgba(63, 63, 68, 0.05), 0 1px 3px 0 var(--shadow-color);
|
||||
}
|
||||
|
||||
&.content {
|
||||
position: relative;
|
||||
|
||||
transform: translateY(-30px);
|
||||
padding-top: 35px;
|
||||
|
||||
z-index: 45;
|
||||
}
|
||||
}
|
||||
}
|
@ -4,25 +4,10 @@ import { Motion, spring } from "react-motion"
|
||||
|
||||
import useLayoutInterface from "hooks/useLayoutInterface"
|
||||
import useDefaultVisibility from "hooks/useDefaultVisibility"
|
||||
import useTopBar from "hooks/useTopBar"
|
||||
|
||||
import "./index.less"
|
||||
|
||||
export const UseTopBar = (props) => {
|
||||
app.layout.top_bar.render(
|
||||
<React.Fragment>
|
||||
{props.children}
|
||||
</React.Fragment>,
|
||||
props.options)
|
||||
|
||||
React.useEffect(() => {
|
||||
return () => {
|
||||
app.layout.top_bar.renderDefault()
|
||||
}
|
||||
}, [])
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
export default (props) => {
|
||||
const [visible, setVisible] = useDefaultVisibility()
|
||||
const [shouldUseTopBarSpacer, setShouldUseTopBarSpacer] = React.useState(true)
|
||||
@ -45,7 +30,7 @@ export default (props) => {
|
||||
setRender(null)
|
||||
},
|
||||
shouldUseTopBarSpacer: (to) => {
|
||||
app.layout.toogleTopBarSpacer(to)
|
||||
app.layout.toggleTopBarSpacer(to)
|
||||
setShouldUseTopBarSpacer(to)
|
||||
}
|
||||
})
|
||||
@ -69,27 +54,27 @@ export default (props) => {
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!shouldUseTopBarSpacer) {
|
||||
app.layout.tooglePagePanelSpacer(true)
|
||||
app.layout.togglePagePanelSpacer(true)
|
||||
} else {
|
||||
app.layout.tooglePagePanelSpacer(false)
|
||||
app.layout.togglePagePanelSpacer(false)
|
||||
}
|
||||
}, [shouldUseTopBarSpacer])
|
||||
|
||||
React.useEffect(() => {
|
||||
if (shouldUseTopBarSpacer) {
|
||||
if (visible) {
|
||||
app.layout.toogleTopBarSpacer(true)
|
||||
app.layout.toggleTopBarSpacer(true)
|
||||
} else {
|
||||
app.layout.toogleTopBarSpacer(false)
|
||||
app.layout.toggleTopBarSpacer(false)
|
||||
}
|
||||
} else {
|
||||
if (visible) {
|
||||
app.layout.tooglePagePanelSpacer(true)
|
||||
app.layout.togglePagePanelSpacer(true)
|
||||
} else {
|
||||
app.layout.tooglePagePanelSpacer(false)
|
||||
app.layout.togglePagePanelSpacer(false)
|
||||
}
|
||||
|
||||
app.layout.toogleTopBarSpacer(false)
|
||||
app.layout.toggleTopBarSpacer(false)
|
||||
}
|
||||
}, [visible])
|
||||
|
||||
|
@ -51,12 +51,12 @@ export default class Login extends React.Component {
|
||||
}
|
||||
|
||||
this.clearError()
|
||||
this.toogleLoading(true)
|
||||
this.toggleLoading(true)
|
||||
|
||||
const loginProcess = await AuthModel.login(payload).catch((error) => {
|
||||
console.error(error, error.response)
|
||||
|
||||
this.toogleLoading(false)
|
||||
this.toggleLoading(false)
|
||||
this.onError(error.response.data.message)
|
||||
|
||||
return false
|
||||
@ -86,7 +86,7 @@ export default class Login extends React.Component {
|
||||
app.eventBus.emit("app.createRegister")
|
||||
}
|
||||
|
||||
toogleLoading = (to) => {
|
||||
toggleLoading = (to) => {
|
||||
if (typeof to === "undefined") {
|
||||
to = !this.state.loading
|
||||
}
|
||||
@ -129,11 +129,11 @@ export default class Login extends React.Component {
|
||||
const phase = phasesToSteps[this.state.phase]
|
||||
|
||||
if (typeof stepsValidations[phase] === "function") {
|
||||
this.toogleLoading(true)
|
||||
this.toggleLoading(true)
|
||||
|
||||
const result = await stepsValidations[phase](this.state.loginInputs)
|
||||
|
||||
this.toogleLoading(false)
|
||||
this.toggleLoading(false)
|
||||
|
||||
if (!result) {
|
||||
this.formRef.current.setFields([
|
||||
|
@ -10,13 +10,13 @@ const NavMenu = (props) => {
|
||||
}
|
||||
|
||||
return <div className="navmenu_wrapper">
|
||||
{
|
||||
props.header && <div className="card header" id="navMenu">
|
||||
{props.header}
|
||||
</div>
|
||||
}
|
||||
<div className="card">
|
||||
{
|
||||
props.header && <div className="card_header">
|
||||
{props.header}
|
||||
</div>
|
||||
}
|
||||
|
||||
<div className="card content" id="navMenu">
|
||||
<antd.Menu
|
||||
mode="inline"
|
||||
selectedKeys={[props.activeKey]}
|
||||
|
@ -2,6 +2,60 @@
|
||||
|
||||
.navmenu_wrapper {
|
||||
position: relative;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
.card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
background-color: var(--background-color-accent);
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
|
||||
width: 100%;
|
||||
|
||||
h1,
|
||||
h2 {
|
||||
width: fit-content;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.card_header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
margin-bottom: 10px;
|
||||
|
||||
view-transition-name: main-header;
|
||||
|
||||
h1 {
|
||||
view-transition-name: main-header-text;
|
||||
}
|
||||
}
|
||||
|
||||
&.content {
|
||||
position: relative;
|
||||
|
||||
transform: translateY(-30px);
|
||||
padding-top: 35px;
|
||||
|
||||
z-index: 45;
|
||||
}
|
||||
}
|
||||
|
||||
&.card:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.__mobile__navmenu_wrapper {
|
||||
|
@ -4,7 +4,6 @@ import * as antd from "antd"
|
||||
|
||||
import { createIconRender } from "components/Icons"
|
||||
|
||||
import { UseTopBar } from "components/Layout/topBar"
|
||||
import NavMenu from "./components/NavMenu"
|
||||
|
||||
import "./index.less"
|
||||
@ -33,12 +32,16 @@ export class PagePanelWithNavMenu extends React.Component {
|
||||
componentDidMount() {
|
||||
if (app.isMobile) {
|
||||
app.layout.top_bar.shouldUseTopBarSpacer(false)
|
||||
} else {
|
||||
app.layout.toggleCenteredContent(true)
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (app.isMobile) {
|
||||
app.layout.top_bar.shouldUseTopBarSpacer(true)
|
||||
} else {
|
||||
app.layout.toggleCenteredContent(false)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@
|
||||
.pagePanels {
|
||||
display: grid;
|
||||
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
grid-template-columns: 1fr 3fr;
|
||||
grid-template-rows: 1fr;
|
||||
grid-column-gap: 20px;
|
||||
grid-row-gap: 0px;
|
||||
@ -104,57 +104,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
background-color: var(--background-color-accent);
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
|
||||
width: 20vw;
|
||||
min-width: 250px;
|
||||
|
||||
isolation: isolate;
|
||||
|
||||
h1,
|
||||
h2 {
|
||||
width: fit-content;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&.header {
|
||||
position: relative;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
width: 100%;
|
||||
|
||||
margin-bottom: 10px;
|
||||
|
||||
z-index: 50;
|
||||
|
||||
-webkit-box-shadow: 0 0 0 1px rgba(63, 63, 68, 0.05), 0 1px 3px 0 var(--shadow-color);
|
||||
-moz-box-shadow: 0 0 0 1px rgba(63, 63, 68, 0.05), 0 1px 3px 0 var(--shadow-color);
|
||||
box-shadow: 0 0 0 1px rgba(63, 63, 68, 0.05), 0 1px 3px 0 var(--shadow-color);
|
||||
}
|
||||
|
||||
&.content {
|
||||
position: relative;
|
||||
|
||||
transform: translateY(-30px);
|
||||
padding-top: 35px;
|
||||
|
||||
z-index: 45;
|
||||
}
|
||||
}
|
||||
|
||||
&.card:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
@ -37,7 +37,7 @@ export class BackgroundMediaPlayer extends React.Component {
|
||||
events = {
|
||||
"sidebar.expanded": (to) => {
|
||||
if (!to) {
|
||||
this.toogleExpand(false)
|
||||
this.toggleExpand(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -46,7 +46,7 @@ export class BackgroundMediaPlayer extends React.Component {
|
||||
app.cores.player.minimize()
|
||||
}
|
||||
|
||||
toogleExpand = (to) => {
|
||||
toggleExpand = (to) => {
|
||||
if (typeof to !== "boolean") {
|
||||
to = !this.state.expanded
|
||||
}
|
||||
@ -91,7 +91,7 @@ export class BackgroundMediaPlayer extends React.Component {
|
||||
|
||||
<div
|
||||
className="background_media_player__row"
|
||||
onClick={this.toogleExpand}
|
||||
onClick={this.toggleExpand}
|
||||
>
|
||||
<div
|
||||
id="sidebar_item_icon"
|
||||
@ -166,7 +166,7 @@ export class BackgroundMediaPlayer extends React.Component {
|
||||
type="ghost"
|
||||
shape="circle"
|
||||
icon={this.context.playbackStatus === "playing" ? <Icons.MdPause /> : <Icons.MdPlayArrow />}
|
||||
onClick={app.cores.player.playback.toogle}
|
||||
onClick={app.cores.player.playback.toggle}
|
||||
/>
|
||||
|
||||
<antd.Button
|
||||
|
@ -59,7 +59,7 @@ export default ({
|
||||
type="primary"
|
||||
shape="circle"
|
||||
icon={streamMode ? <Icons.MdStop /> : playbackStatus === "playing" ? <Icons.MdPause /> : <Icons.MdPlayArrow />}
|
||||
onClick={() => onClickActionsButton("toogle")}
|
||||
onClick={() => onClickActionsButton("toggle")}
|
||||
className="playButton"
|
||||
disabled={syncModeLocked}
|
||||
>
|
||||
|
@ -57,8 +57,8 @@ export class AudioPlayer extends React.Component {
|
||||
app.cores.player.volume(value)
|
||||
}
|
||||
|
||||
toogleMute = () => {
|
||||
app.cores.player.toogleMute()
|
||||
toggleMute = () => {
|
||||
app.cores.player.toggleMute()
|
||||
}
|
||||
|
||||
onClickPlayButton = () => {
|
||||
@ -66,7 +66,7 @@ export class AudioPlayer extends React.Component {
|
||||
return app.cores.player.playback.stop()
|
||||
}
|
||||
|
||||
app.cores.player.playback.toogle()
|
||||
app.cores.player.playback.toggle()
|
||||
}
|
||||
|
||||
onClickPreviousButton = () => {
|
||||
@ -168,10 +168,10 @@ export class AudioPlayer extends React.Component {
|
||||
audioMuted={this.context.audioMuted}
|
||||
audioVolume={this.context.audioVolume}
|
||||
onVolumeUpdate={this.updateVolume}
|
||||
onMuteUpdate={this.toogleMute}
|
||||
onMuteUpdate={this.toggleMute}
|
||||
controls={{
|
||||
previous: this.onClickPreviousButton,
|
||||
toogle: this.onClickPlayButton,
|
||||
toggle: this.onClickPlayButton,
|
||||
next: this.onClickNextButton,
|
||||
}}
|
||||
/>
|
||||
|
@ -104,8 +104,8 @@ export default class PostCard extends React.PureComponent {
|
||||
to = !this.state.open
|
||||
}
|
||||
|
||||
if (typeof this.props.events?.onToogleOpen === "function") {
|
||||
this.props.events?.onToogleOpen(to, this.props.data)
|
||||
if (typeof this.props.events?.ontoggleOpen === "function") {
|
||||
this.props.events?.ontoggleOpen(to, this.props.data)
|
||||
}
|
||||
|
||||
this.setState({
|
||||
|
@ -41,7 +41,7 @@ export default class PostCreator extends React.Component {
|
||||
})
|
||||
}
|
||||
|
||||
toogleUploaderVisibility = (to) => {
|
||||
toggleUploaderVisibility = (to) => {
|
||||
to = to ?? !this.state.uploaderVisible
|
||||
|
||||
if (to === this.state.uploaderVisible) {
|
||||
@ -115,7 +115,7 @@ export default class PostCreator extends React.Component {
|
||||
|
||||
uploadFile = async (req) => {
|
||||
// hide uploader
|
||||
this.toogleUploaderVisibility(false)
|
||||
this.toggleUploaderVisibility(false)
|
||||
|
||||
const request = await app.cores.remoteStorage.uploadFile(req.file)
|
||||
.catch(error => {
|
||||
@ -180,7 +180,7 @@ export default class PostCreator extends React.Component {
|
||||
|
||||
switch (change.file.status) {
|
||||
case "uploading": {
|
||||
this.toogleUploaderVisibility(false)
|
||||
this.toggleUploaderVisibility(false)
|
||||
|
||||
this.setState({
|
||||
pending: [...this.state.pending, change.file.uid]
|
||||
@ -377,11 +377,11 @@ export default class PostCreator extends React.Component {
|
||||
console.log(event)
|
||||
|
||||
if (event.type === "dragenter") {
|
||||
this.toogleUploaderVisibility(true)
|
||||
this.toggleUploaderVisibility(true)
|
||||
} else if (event.type === "dragleave") {
|
||||
// check if mouse is over the uploader or outside the creatorRef
|
||||
if (this.state.uploaderVisible && !this.creatorRef.current.contains(event.target)) {
|
||||
this.toogleUploaderVisibility(false)
|
||||
this.toggleUploaderVisibility(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -342,7 +342,7 @@ export class PostsListsComponent extends React.Component {
|
||||
}
|
||||
|
||||
onLikePost = async (data) => {
|
||||
let result = await PostModel.toogleLike({ post_id: data._id }).catch(() => {
|
||||
let result = await PostModel.toggleLike({ post_id: data._id }).catch(() => {
|
||||
antd.message.error("Failed to like post")
|
||||
|
||||
return false
|
||||
@ -352,7 +352,7 @@ export class PostsListsComponent extends React.Component {
|
||||
}
|
||||
|
||||
onSavePost = async (data) => {
|
||||
let result = await PostModel.toogleSave({ post_id: data._id }).catch(() => {
|
||||
let result = await PostModel.toggleSave({ post_id: data._id }).catch(() => {
|
||||
antd.message.error("Failed to save post")
|
||||
|
||||
return false
|
||||
@ -376,7 +376,7 @@ export class PostsListsComponent extends React.Component {
|
||||
})
|
||||
}
|
||||
|
||||
onToogleOpen = (to, data) => {
|
||||
ontoggleOpen = (to, data) => {
|
||||
if (typeof this.props.onOpenPost === "function") {
|
||||
this.props.onOpenPost(to, data)
|
||||
}
|
||||
|
@ -111,10 +111,10 @@ class DefaultWindowRender extends React.Component {
|
||||
this.setState({ position: this.getCenterPosition() })
|
||||
}
|
||||
|
||||
this.toogleVisibility(true)
|
||||
this.toggleVisibility(true)
|
||||
}
|
||||
|
||||
toogleVisibility = (to) => {
|
||||
toggleVisibility = (to) => {
|
||||
this.setState({ visible: to ?? !this.state.visible })
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,6 @@
|
||||
.shortable-list {
|
||||
position: relative;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
|
@ -105,7 +105,7 @@ export default class SyncRoomCard extends React.Component {
|
||||
app.cores.sync.music.leaveRoom()
|
||||
}
|
||||
|
||||
toogleChatVisibility = (to) => {
|
||||
toggleChatVisibility = (to) => {
|
||||
if (typeof to !== "boolean") {
|
||||
to = !this.state.chatVisible
|
||||
}
|
||||
@ -182,7 +182,7 @@ export default class SyncRoomCard extends React.Component {
|
||||
<Button
|
||||
size="small"
|
||||
icon={<Icons.MdChat />}
|
||||
onClick={this.toogleChatVisibility}
|
||||
onClick={this.toggleChatVisibility}
|
||||
/>
|
||||
</Badge>
|
||||
</div>
|
||||
|
@ -80,7 +80,7 @@ export const WidgetBrowser = (props) => {
|
||||
})
|
||||
}}
|
||||
onChangeVisible={(visible) => {
|
||||
app.cores.widgets.toogleVisibility(widget._id, visible)
|
||||
app.cores.widgets.toggleVisibility(widget._id, visible)
|
||||
}}
|
||||
/>
|
||||
</React.Fragment>
|
||||
|
@ -207,6 +207,27 @@ export default class WidgetsWrapper extends React.Component {
|
||||
widgetsRender: getWidgets(),
|
||||
}
|
||||
|
||||
events = {
|
||||
"widgets:installed": () => {
|
||||
this.loadWidgets()
|
||||
},
|
||||
"widgets:uninstalled": () => {
|
||||
this.loadWidgets()
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
for (const [eventName, eventHandler] of Object.entries(this.events)) {
|
||||
app.eventBus.on(eventName, eventHandler)
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
for (const [eventName, eventHandler] of Object.entries(this.events)) {
|
||||
app.eventBus.off(eventName, eventHandler)
|
||||
}
|
||||
}
|
||||
|
||||
handleOnSortEnd = (widgetsRender) => {
|
||||
this.setState({
|
||||
widgetsRender
|
||||
@ -215,6 +236,12 @@ export default class WidgetsWrapper extends React.Component {
|
||||
app.cores.widgets.sort(widgetsRender)
|
||||
}
|
||||
|
||||
loadWidgets = () => {
|
||||
this.setState({
|
||||
widgetsRender: getWidgets(),
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div className="widgets_wrapper">
|
||||
<SortableList
|
||||
|
@ -1,7 +1,7 @@
|
||||
.widgets_wrapper {
|
||||
gap: 20px;
|
||||
position: relative;
|
||||
|
||||
width: 20vw;
|
||||
gap: 20px;
|
||||
|
||||
.widgets_wrapper_list {
|
||||
display: flex;
|
||||
|
@ -135,13 +135,13 @@ class MediaSession {
|
||||
|
||||
// External controls (iOS only)
|
||||
case "music-controls-toggle-play-pause": {
|
||||
return app.cores.player.playback.toogle()
|
||||
return app.cores.player.playback.toggle()
|
||||
}
|
||||
|
||||
// Headset events (Android only)
|
||||
// All media button events are listed below
|
||||
case "music-controls-media-button": {
|
||||
return app.cores.player.playback.toogle()
|
||||
return app.cores.player.playback.toggle()
|
||||
}
|
||||
case "music-controls-headset-unplugged": {
|
||||
return app.cores.player.playback.pause()
|
||||
@ -211,8 +211,8 @@ export default class Player extends Core {
|
||||
audioContext: this.audioContext,
|
||||
attachPlayerComponent: this.attachPlayerComponent.bind(this),
|
||||
detachPlayerComponent: this.detachPlayerComponent.bind(this),
|
||||
toogleMute: this.toogleMute.bind(this),
|
||||
minimize: this.toogleMinimize.bind(this),
|
||||
toggleMute: this.toggleMute.bind(this),
|
||||
minimize: this.toggleMinimize.bind(this),
|
||||
volume: this.volume.bind(this),
|
||||
start: this.start.bind(this),
|
||||
startPlaylist: this.startPlaylist.bind(this),
|
||||
@ -267,7 +267,7 @@ export default class Player extends Core {
|
||||
|
||||
return this.state.playbackMode
|
||||
}.bind(this),
|
||||
toogle: function () {
|
||||
toggle: function () {
|
||||
if (!this.currentAudioInstance) {
|
||||
console.error("No audio instance")
|
||||
return null
|
||||
@ -304,7 +304,7 @@ export default class Player extends Core {
|
||||
duration: this.duration.bind(this),
|
||||
velocity: this.velocity.bind(this),
|
||||
close: this.close.bind(this),
|
||||
toogleSyncMode: this.toogleSyncMode.bind(this),
|
||||
toggleSyncMode: this.toggleSyncMode.bind(this),
|
||||
currentState: this.currentState.bind(this),
|
||||
setSampleRate: this.setSampleRate.bind(this),
|
||||
}
|
||||
@ -1073,7 +1073,7 @@ export default class Player extends Core {
|
||||
this.detachPlayerComponent()
|
||||
}
|
||||
|
||||
toogleMute(to) {
|
||||
toggleMute(to) {
|
||||
if (app.isMobile) {
|
||||
console.warn("Cannot mute on mobile")
|
||||
return false
|
||||
@ -1088,7 +1088,7 @@ export default class Player extends Core {
|
||||
return this.state.audioMuted
|
||||
}
|
||||
|
||||
toogleMinimize(to) {
|
||||
toggleMinimize(to) {
|
||||
this.state.minimized = to ?? !this.state.minimized
|
||||
|
||||
return this.state.minimized
|
||||
@ -1202,7 +1202,7 @@ export default class Player extends Core {
|
||||
return this.state.collapsed
|
||||
}
|
||||
|
||||
toogleSyncMode(to, lock) {
|
||||
toggleSyncMode(to, lock) {
|
||||
if (typeof to !== "boolean") {
|
||||
console.warn("Sync mode must be a boolean")
|
||||
return false
|
||||
|
@ -154,7 +154,7 @@ export default class StyleCore extends Core {
|
||||
}
|
||||
|
||||
onEvents = {
|
||||
"style.autoDarkModeToogle": (value) => {
|
||||
"style.autoDarkModetoggle": (value) => {
|
||||
if (value === true) {
|
||||
return this.applyVariant(StyleCore.variant)
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ class MusicSyncSubCore {
|
||||
this.currentRoomData = data
|
||||
|
||||
// check if user is owner
|
||||
app.cores.player.toogleSyncMode(true, data.ownerUserId !== app.userData._id)
|
||||
app.cores.player.toggleSyncMode(true, data.ownerUserId !== app.userData._id)
|
||||
|
||||
this.startSendStateInterval()
|
||||
|
||||
@ -78,7 +78,7 @@ class MusicSyncSubCore {
|
||||
|
||||
this.currentRoomData = null
|
||||
|
||||
app.cores.player.toogleSyncMode(false, false)
|
||||
app.cores.player.toggleSyncMode(false, false)
|
||||
|
||||
this.eventBus.emit("room:left", data)
|
||||
},
|
||||
@ -96,7 +96,7 @@ class MusicSyncSubCore {
|
||||
type: "error",
|
||||
})
|
||||
|
||||
app.cores.player.toogleSyncMode(false, false)
|
||||
app.cores.player.toggleSyncMode(false, false)
|
||||
},
|
||||
|
||||
"room:user:joined": (data) => {
|
||||
@ -114,7 +114,7 @@ class MusicSyncSubCore {
|
||||
"room:owner:changed": (data) => {
|
||||
const isSelf = data.ownerUserId === app.userData._id
|
||||
|
||||
app.cores.player.toogleSyncMode(true, !isSelf)
|
||||
app.cores.player.toggleSyncMode(true, !isSelf)
|
||||
|
||||
app.cores.player.playback.stop()
|
||||
|
||||
@ -173,7 +173,7 @@ class MusicSyncSubCore {
|
||||
|
||||
this.currentRoomData = null
|
||||
|
||||
app.cores.player.toogleSyncMode(false, false)
|
||||
app.cores.player.toggleSyncMode(false, false)
|
||||
|
||||
app.notification.new({
|
||||
title: "Kicked",
|
||||
|
@ -14,7 +14,7 @@ export default class WidgetsCore extends Core {
|
||||
isInstalled: this.isInstalled.bind(this),
|
||||
install: this.install.bind(this),
|
||||
uninstall: this.uninstall.bind(this),
|
||||
toogleVisibility: this.toogleVisibility.bind(this),
|
||||
toggleVisibility: this.toggleVisibility.bind(this),
|
||||
isVisible: this.isVisible.bind(this),
|
||||
sort: this.sort.bind(this),
|
||||
}
|
||||
@ -154,7 +154,7 @@ export default class WidgetsCore extends Core {
|
||||
return true
|
||||
}
|
||||
|
||||
toogleVisibility(widget_id, to) {
|
||||
toggleVisibility(widget_id, to) {
|
||||
if (!widget_id || typeof widget_id !== "string") {
|
||||
throw new Error("Widget id must be a string.")
|
||||
}
|
||||
|
@ -2,10 +2,10 @@ import React from "react"
|
||||
|
||||
export default () => {
|
||||
React.useEffect(() => {
|
||||
app.layout.toogleCenteredContent(true)
|
||||
app.layout.toggleCenteredContent(true)
|
||||
|
||||
return () => {
|
||||
app.layout.toogleCenteredContent(false)
|
||||
app.layout.toggleCenteredContent(false)
|
||||
}
|
||||
}, [])
|
||||
}
|
17
packages/app/src/hooks/useTopBar/index.jsx
Normal file
17
packages/app/src/hooks/useTopBar/index.jsx
Normal file
@ -0,0 +1,17 @@
|
||||
import React from "react"
|
||||
|
||||
export default (props) => {
|
||||
app.layout.top_bar.render(
|
||||
<React.Fragment>
|
||||
{props.children}
|
||||
</React.Fragment>,
|
||||
props.options)
|
||||
|
||||
React.useEffect(() => {
|
||||
return () => {
|
||||
app.layout.top_bar.renderDefault()
|
||||
}
|
||||
}, [])
|
||||
|
||||
return null
|
||||
}
|
@ -45,8 +45,12 @@ export default class Layout extends React.PureComponent {
|
||||
|
||||
transitionLayer.classList.remove("fade-opacity-leave")
|
||||
},
|
||||
"router.navigate": (path, options) => {
|
||||
this.makePageTransition(path, options)
|
||||
"router.navigate": async (path, options) => {
|
||||
this.progressBar.start()
|
||||
|
||||
await this.makePageTransition(options)
|
||||
|
||||
this.progressBar.done()
|
||||
},
|
||||
}
|
||||
|
||||
@ -57,11 +61,11 @@ export default class Layout extends React.PureComponent {
|
||||
})
|
||||
|
||||
if (app.isMobile) {
|
||||
this.layoutInterface.toogleMobileStyle(true)
|
||||
this.layoutInterface.toggleMobileStyle(true)
|
||||
}
|
||||
|
||||
if (app.cores.settings.get("reduceAnimations")) {
|
||||
this.layoutInterface.toogleRootContainerClassname("reduce-animations", true)
|
||||
this.layoutInterface.toggleRootContainerClassname("reduce-animations", true)
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,26 +80,31 @@ export default class Layout extends React.PureComponent {
|
||||
this.setState({ renderError: { info, stack } })
|
||||
}
|
||||
|
||||
makePageTransition(path, options = {}) {
|
||||
this.progressBar.start()
|
||||
async makePageTransition(options = {}) {
|
||||
if (document.startViewTransition) {
|
||||
return document.startViewTransition(async () => {
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, options.state?.transitionDelay ?? 250)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const content_layout = document.getElementById("content_layout")
|
||||
|
||||
if (!content_layout) {
|
||||
console.warn("content_layout not found, no animation will be played")
|
||||
|
||||
this.progressBar.done()
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
content_layout.classList.add("fade-transverse-leave")
|
||||
|
||||
setTimeout(() => {
|
||||
this.progressBar.done()
|
||||
|
||||
content_layout.classList.remove("fade-transverse-leave")
|
||||
}, options.state?.transitionDelay ?? 250)
|
||||
return await new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve()
|
||||
content_layout.classList.remove("fade-transverse-leave")
|
||||
}, options.state?.transitionDelay ?? 250)
|
||||
})
|
||||
}
|
||||
|
||||
layoutInterface = window.app.layout = {
|
||||
@ -110,22 +119,22 @@ export default class Layout extends React.PureComponent {
|
||||
layoutType: layout,
|
||||
})
|
||||
},
|
||||
toogleCenteredContent: (to) => {
|
||||
return this.layoutInterface.toogleRootContainerClassname("centered-content", to)
|
||||
toggleCenteredContent: (to) => {
|
||||
return this.layoutInterface.toggleRootContainerClassname("centered-content", to)
|
||||
},
|
||||
toogleMobileStyle: (to) => {
|
||||
return this.layoutInterface.toogleRootContainerClassname("mobile", to)
|
||||
toggleMobileStyle: (to) => {
|
||||
return this.layoutInterface.toggleRootContainerClassname("mobile", to)
|
||||
},
|
||||
toogleReducedAnimations: (to) => {
|
||||
return this.layoutInterface.toogleRootContainerClassname("reduce-animations", to)
|
||||
toggleReducedAnimations: (to) => {
|
||||
return this.layoutInterface.toggleRootContainerClassname("reduce-animations", to)
|
||||
},
|
||||
toogleTopBarSpacer: (to) => {
|
||||
return this.layoutInterface.toogleRootContainerClassname("top-bar-spacer", to)
|
||||
toggleTopBarSpacer: (to) => {
|
||||
return this.layoutInterface.toggleRootContainerClassname("top-bar-spacer", to)
|
||||
},
|
||||
tooglePagePanelSpacer: (to) => {
|
||||
return this.layoutInterface.toogleRootContainerClassname("page-panel-spacer", to)
|
||||
togglePagePanelSpacer: (to) => {
|
||||
return this.layoutInterface.toggleRootContainerClassname("page-panel-spacer", to)
|
||||
},
|
||||
toogleRootContainerClassname: (classname, to) => {
|
||||
toggleRootContainerClassname: (classname, to) => {
|
||||
const root = document.getElementById("root")
|
||||
|
||||
if (!root) {
|
||||
|
@ -80,7 +80,7 @@ export default class FloatingStack extends React.Component {
|
||||
|
||||
return true
|
||||
},
|
||||
toogleGlobalVisibility: (to) => {
|
||||
toggleGlobalVisibility: (to) => {
|
||||
if (typeof to !== "boolean") {
|
||||
to = !this.state.globalVisibility
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import React from "react"
|
||||
import classnames from "classnames"
|
||||
import { Layout } from "antd"
|
||||
|
||||
import { Sidebar, Drawer, Sidedrawer, Modal, BottomBar, TopBar } from "components/Layout"
|
||||
import { Sidebar, Drawer, Sidedrawer, Modal, BottomBar, TopBar, ToolsBar } from "components/Layout"
|
||||
|
||||
import BackgroundDecorator from "components/BackgroundDecorator"
|
||||
|
||||
@ -40,6 +40,7 @@ const DesktopLayout = (props) => {
|
||||
React.cloneElement(props.children, props)
|
||||
}
|
||||
</Layout.Content>
|
||||
<ToolsBar />
|
||||
</Layout>
|
||||
</>
|
||||
}
|
||||
@ -64,7 +65,6 @@ const MobileLayout = (props) => {
|
||||
</Layout.Content>
|
||||
|
||||
<BottomBar />
|
||||
<Sidedrawer />
|
||||
<Drawer />
|
||||
</Layout>
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ export default class Account extends React.Component {
|
||||
}
|
||||
|
||||
onClickFollow = async () => {
|
||||
const result = await FollowsModel.toogleFollow({
|
||||
const result = await FollowsModel.toggleFollow({
|
||||
username: this.state.requestedUser,
|
||||
}).catch((error) => {
|
||||
console.error(error)
|
||||
@ -159,7 +159,7 @@ export default class Account extends React.Component {
|
||||
})
|
||||
}
|
||||
|
||||
toogleCoverExpanded = async (to) => {
|
||||
toggleCoverExpanded = async (to) => {
|
||||
this.setState({
|
||||
coverExpanded: to ?? !this.state.coverExpanded,
|
||||
})
|
||||
@ -217,7 +217,7 @@ export default class Account extends React.Component {
|
||||
})}
|
||||
ref={this.coverComponent}
|
||||
style={{ backgroundImage: `url("${user.cover}")` }}
|
||||
onClick={() => this.toogleCoverExpanded()}
|
||||
onClick={() => this.toggleCoverExpanded()}
|
||||
id="profile-cover"
|
||||
/>
|
||||
}
|
||||
|
@ -27,41 +27,9 @@ export default class Home extends React.Component {
|
||||
</antd.Button>
|
||||
</>
|
||||
|
||||
const extraPanel = {
|
||||
children: <>
|
||||
<div className="card" id="trendings">
|
||||
<div className="header">
|
||||
<h2>
|
||||
<Icons.TrendingUp />
|
||||
<Translation>{(t) => t("Trendings")}</Translation>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<HashtagTrendings />
|
||||
</div>
|
||||
|
||||
<div className="card" id="onlineFriends">
|
||||
<div className="header">
|
||||
<h2>
|
||||
<Icons.MdPeopleAlt />
|
||||
<Translation>{(t) => t("Online Friends")}</Translation>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<ConnectedFriends />
|
||||
</div>
|
||||
|
||||
<WidgetsWrapper />
|
||||
</>
|
||||
}
|
||||
|
||||
return <PagePanelWithNavMenu
|
||||
tabs={Tabs}
|
||||
navMenuHeader={navMenuHeader}
|
||||
extraMenuItems={[
|
||||
<FeaturedEventsAnnouncements />
|
||||
]}
|
||||
extraPanel={extraPanel}
|
||||
primaryPanelClassName="full"
|
||||
useSetQueryType
|
||||
transition
|
||||
|
@ -128,7 +128,7 @@ class PlayerController extends React.Component {
|
||||
app.cores.player.playback.next()
|
||||
}
|
||||
|
||||
onClickTooglePlayButton = () => {
|
||||
onClicktogglePlayButton = () => {
|
||||
if (this.state?.playbackStatus === "playing") {
|
||||
app.cores.player.playback.pause()
|
||||
} else {
|
||||
@ -140,8 +140,8 @@ class PlayerController extends React.Component {
|
||||
app.cores.player.volume(value)
|
||||
}
|
||||
|
||||
toogleMute = () => {
|
||||
app.cores.player.toogleMute()
|
||||
toggleMute = () => {
|
||||
app.cores.player.toggleMute()
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@ -250,7 +250,7 @@ class PlayerController extends React.Component {
|
||||
className="player_controller_controls"
|
||||
controls={{
|
||||
previous: this.onClickPreviousButton,
|
||||
toogle: this.onClickTooglePlayButton,
|
||||
toggle: this.onClicktogglePlayButton,
|
||||
next: this.onClickNextButton,
|
||||
}}
|
||||
syncModeLocked={this.state.syncModeLocked}
|
||||
@ -259,7 +259,7 @@ class PlayerController extends React.Component {
|
||||
audioVolume={this.state.audioVolume}
|
||||
audioMuted={this.state.audioMuted}
|
||||
onVolumeUpdate={this.updateVolume}
|
||||
onMuteUpdate={this.toogleMute}
|
||||
onMuteUpdate={this.toggleMute}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -341,7 +341,7 @@ export default class SyncLyrics extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
toogleClassName = (className, to) => {
|
||||
toggleClassName = (className, to) => {
|
||||
if (typeof to === "undefined") {
|
||||
to = !this.state.classnames[className]
|
||||
}
|
||||
@ -379,16 +379,16 @@ export default class SyncLyrics extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
toogleVideoCanvas = (to) => {
|
||||
return this.toogleClassName("video-canvas-enabled", to)
|
||||
toggleVideoCanvas = (to) => {
|
||||
return this.toggleClassName("video-canvas-enabled", to)
|
||||
}
|
||||
|
||||
toogleCenteredControllerMode = (to) => {
|
||||
return this.toogleClassName("centered-player", to)
|
||||
toggleCenteredControllerMode = (to) => {
|
||||
return this.toggleClassName("centered-player", to)
|
||||
}
|
||||
|
||||
toogleCinematicMode = (to) => {
|
||||
return this.toogleClassName("cinematic-mode", to)
|
||||
toggleCinematicMode = (to) => {
|
||||
return this.toggleClassName("cinematic-mode", to)
|
||||
}
|
||||
|
||||
isCurrentLine = (line) => {
|
||||
@ -461,27 +461,27 @@ export default class SyncLyrics extends React.Component {
|
||||
//app.message.info("Video canvas loaded")
|
||||
console.log(`[SyncLyrics] Video canvas loaded`)
|
||||
|
||||
this.toogleVideoCanvas(true)
|
||||
this.toggleVideoCanvas(true)
|
||||
} else {
|
||||
//app.message.info("No video canvas available for this song")
|
||||
console.log(`[SyncLyrics] No video canvas available for this song`)
|
||||
|
||||
this.toogleVideoCanvas(false)
|
||||
this.toggleVideoCanvas(false)
|
||||
}
|
||||
|
||||
// if has no lyrics or are unsynced, toogle cinematic mode off and center controller
|
||||
// if has no lyrics or are unsynced, toggle cinematic mode off and center controller
|
||||
if (data.lines.length === 0 || data.syncType !== "LINE_SYNCED") {
|
||||
//app.message.info("No lyrics available for this song")
|
||||
|
||||
console.log(`[SyncLyrics] No lyrics available for this song, sync type [${data.syncType}]`)
|
||||
|
||||
this.toogleCinematicMode(false)
|
||||
this.toogleCenteredControllerMode(true)
|
||||
this.toggleCinematicMode(false)
|
||||
this.toggleCenteredControllerMode(true)
|
||||
} else {
|
||||
//app.message.info("Lyrics loaded, starting sync...")
|
||||
console.log(`[SyncLyrics] Starting sync with type [${data.syncType}]`)
|
||||
|
||||
this.toogleCenteredControllerMode(false)
|
||||
this.toggleCenteredControllerMode(false)
|
||||
this.startLyricsSync()
|
||||
}
|
||||
|
||||
@ -519,7 +519,7 @@ export default class SyncLyrics extends React.Component {
|
||||
|
||||
if (!hasStartedFirst) {
|
||||
if (this.state.canvas_url) {
|
||||
this.toogleCinematicMode(true)
|
||||
this.toggleCinematicMode(true)
|
||||
}
|
||||
|
||||
return false
|
||||
@ -567,15 +567,15 @@ export default class SyncLyrics extends React.Component {
|
||||
if (line.words === "♪" || line.words === "♫" || line.words === " " || line.words === "") {
|
||||
//console.log(`[SyncLyrics] Toogling cinematic mode on because line is empty`)
|
||||
|
||||
this.toogleCinematicMode(true)
|
||||
this.toggleCinematicMode(true)
|
||||
} else {
|
||||
//console.log(`[SyncLyrics] Toogling cinematic mode off because line is not empty`)
|
||||
|
||||
this.toogleCinematicMode(false)
|
||||
this.toggleCinematicMode(false)
|
||||
}
|
||||
} else {
|
||||
if (this.state.classnames["cinematic-mode"] === true) {
|
||||
this.toogleCinematicMode(false)
|
||||
this.toggleCinematicMode(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -602,11 +602,7 @@ export default class SyncLyrics extends React.Component {
|
||||
})
|
||||
|
||||
if (app.layout.sidebar) {
|
||||
app.layout.sidebar.toggleVisibility(false)
|
||||
}
|
||||
|
||||
if (app.layout.floatingStack) {
|
||||
app.layout.floatingStack.toogleGlobalVisibility(false)
|
||||
app.controls.toogleUIVisibility(false)
|
||||
}
|
||||
|
||||
app.cores.style.compactMode(true)
|
||||
@ -625,9 +621,9 @@ export default class SyncLyrics extends React.Component {
|
||||
})
|
||||
|
||||
window._hacks = {
|
||||
toogleVideoCanvas: this.toogleVideoCanvas,
|
||||
toogleCinematicMode: this.toogleCinematicMode,
|
||||
toogleCenteredControllerMode: this.toogleCenteredControllerMode,
|
||||
toggleVideoCanvas: this.toggleVideoCanvas,
|
||||
toggleCinematicMode: this.toggleCinematicMode,
|
||||
toggleCenteredControllerMode: this.toggleCenteredControllerMode,
|
||||
}
|
||||
|
||||
await this.loadLyrics()
|
||||
@ -647,11 +643,7 @@ export default class SyncLyrics extends React.Component {
|
||||
delete window._hacks
|
||||
|
||||
if (app.layout.sidebar) {
|
||||
app.layout.sidebar.toggleVisibility(true)
|
||||
}
|
||||
|
||||
if (app.layout.floatingStack) {
|
||||
app.layout.floatingStack.toogleGlobalVisibility(true)
|
||||
app.controls.toogleUIVisibility(true)
|
||||
}
|
||||
|
||||
app.cores.style.compactMode(false)
|
||||
|
@ -193,7 +193,7 @@ export default class SettingItemComponent extends React.PureComponent {
|
||||
return {}
|
||||
}
|
||||
|
||||
toogleLoading = (to) => {
|
||||
toggleLoading = (to) => {
|
||||
if (typeof to === "undefined") {
|
||||
to = !this.state.loading
|
||||
}
|
||||
@ -206,7 +206,7 @@ export default class SettingItemComponent extends React.PureComponent {
|
||||
initialize = async () => {
|
||||
this.perf.start(`init tooks`)
|
||||
|
||||
this.toogleLoading(true)
|
||||
this.toggleLoading(true)
|
||||
|
||||
if (this.props.setting.storaged) {
|
||||
this.perf.start(`get value from storaged`)
|
||||
@ -221,13 +221,13 @@ export default class SettingItemComponent extends React.PureComponent {
|
||||
if (typeof this.props.setting.defaultValue === "function") {
|
||||
this.perf.start(`execute default value fn`)
|
||||
|
||||
this.toogleLoading(true)
|
||||
this.toggleLoading(true)
|
||||
|
||||
this.setState({
|
||||
value: await this.props.setting.defaultValue(this.props.ctx)
|
||||
})
|
||||
|
||||
this.toogleLoading(false)
|
||||
this.toggleLoading(false)
|
||||
|
||||
this.perf.end(`execute default value fn`)
|
||||
}
|
||||
@ -285,7 +285,7 @@ export default class SettingItemComponent extends React.PureComponent {
|
||||
this.perf.end(`Reinitializing setting [${this.props.setting.id}]`)
|
||||
}
|
||||
|
||||
this.toogleLoading(false)
|
||||
this.toggleLoading(false)
|
||||
|
||||
this.perf.end(`init tooks`)
|
||||
|
||||
|
@ -5,7 +5,7 @@ import { Translation } from "react-i18next"
|
||||
import useUrlQueryActiveKey from "hooks/useUrlQueryActiveKey"
|
||||
|
||||
import { Icons, createIconRender } from "components/Icons"
|
||||
import { UseTopBar } from "components/Layout/topBar"
|
||||
import UseTopBar from "hooks/useTopBar"
|
||||
|
||||
import {
|
||||
composedSettingsByGroups as settingsGroups,
|
||||
|
@ -6,20 +6,20 @@ import "./index.less"
|
||||
export default (props) => {
|
||||
const [streamingKeyVisibility, setStreamingKeyVisibility] = React.useState(false)
|
||||
|
||||
const toogleVisibility = (to) => {
|
||||
const toggleVisibility = (to) => {
|
||||
setStreamingKeyVisibility(to ?? !streamingKeyVisibility)
|
||||
}
|
||||
|
||||
return <div className="streamingKeyString">
|
||||
{streamingKeyVisibility ?
|
||||
<>
|
||||
<Icons.EyeOff onClick={() => toogleVisibility()} />
|
||||
<Icons.EyeOff onClick={() => toggleVisibility()} />
|
||||
<code>
|
||||
{props.streamingKey ?? "No streaming key available"}
|
||||
</code>
|
||||
</> :
|
||||
<div
|
||||
onClick={() => toogleVisibility()}
|
||||
onClick={() => toggleVisibility()}
|
||||
>
|
||||
<Icons.Eye />
|
||||
Click to show key
|
||||
|
@ -121,9 +121,9 @@ function generatePageElementWrapper(route, element, bindProps) {
|
||||
}
|
||||
|
||||
if (routeDeclaration.centeredContent) {
|
||||
app.layout.toogleCenteredContent(true)
|
||||
app.layout.toggleCenteredContent(true)
|
||||
} else {
|
||||
app.layout.toogleCenteredContent(false)
|
||||
app.layout.toggleCenteredContent(false)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user