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