mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-11 19:44:15 +00:00
improve mobile mode
This commit is contained in:
parent
163cf09eab
commit
c7a554e455
@ -88,7 +88,7 @@ import { DOMWindow } from "components/RenderWindow"
|
|||||||
|
|
||||||
import { Icons } from "components/Icons"
|
import { Icons } from "components/Icons"
|
||||||
|
|
||||||
import { ThemeProvider } from "cores/style"
|
import { ThemeProvider } from "cores/style/style.core.jsx"
|
||||||
|
|
||||||
import Layout from "./layout"
|
import Layout from "./layout"
|
||||||
import * as Router from "./router"
|
import * as Router from "./router"
|
||||||
|
@ -74,7 +74,7 @@ export default class Drawer extends Component {
|
|||||||
ALLOW_DRAWER_TRANSFORM = true
|
ALLOW_DRAWER_TRANSFORM = true
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.DESKTOP_MODE = !window.isMobile
|
this.DESKTOP_MODE = !app.isMobile
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps, nextState) {
|
componentDidUpdate(prevProps, nextState) {
|
||||||
|
@ -6,31 +6,39 @@ import { Motion, spring } from "react-motion"
|
|||||||
|
|
||||||
import { Icons, createIconRender } from "components/Icons"
|
import { Icons, createIconRender } from "components/Icons"
|
||||||
|
|
||||||
|
import { WithPlayerContext, Context } from "contexts/WithPlayerContext"
|
||||||
|
|
||||||
|
import PlayerView from "pages/@mobile-views/player"
|
||||||
|
|
||||||
import "./index.less"
|
import "./index.less"
|
||||||
|
|
||||||
const items = [
|
const PlayerButton = (props) => {
|
||||||
{
|
const openPlayerView = () => {
|
||||||
id: "creator",
|
app.DrawerController.open("player", PlayerView)
|
||||||
dispatchEvent: "app.openCreator",
|
|
||||||
icon: "PlusCircle",
|
|
||||||
classnames: [["primary"]]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "feed",
|
|
||||||
location: "/home/feed",
|
|
||||||
icon: "Home",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "explore",
|
|
||||||
location: "/home/explore",
|
|
||||||
icon: "Search",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "livestreams",
|
|
||||||
location: "/home/livestreams",
|
|
||||||
icon: "Tv",
|
|
||||||
}
|
}
|
||||||
]
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
openPlayerView()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return <div
|
||||||
|
className={classnames(
|
||||||
|
"player_btn",
|
||||||
|
{
|
||||||
|
"bounce": props.playback === "playing"
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
style={{
|
||||||
|
"--average-color": props.colorAnalysis?.rgba,
|
||||||
|
"--color": props.colorAnalysis?.isDark ? "var(--text-color-white)" : "var(--text-color-black)",
|
||||||
|
}}
|
||||||
|
onClick={openPlayerView}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props.playback === "playing" ? <Icons.MdMusicNote /> : <Icons.MdPause />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
const AccountButton = (props) => {
|
const AccountButton = (props) => {
|
||||||
const user = app.userData
|
const user = app.userData
|
||||||
@ -51,26 +59,10 @@ const AccountButton = (props) => {
|
|||||||
key: "settings",
|
key: "settings",
|
||||||
text: <><Icons.Settings /> <span>Settings</span></>,
|
text: <><Icons.Settings /> <span>Settings</span></>,
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
app.openSettings()
|
app.navigation.goToSettings()
|
||||||
ActionSheetRef.current.close()
|
ActionSheetRef.current.close()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
key: "savedPosts",
|
|
||||||
text: <><Icons.Bookmark /> <span>Saved Posts</span></>,
|
|
||||||
onClick: () => {
|
|
||||||
app.setLocation("/home/savedPosts")
|
|
||||||
ActionSheetRef.current.close()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "about",
|
|
||||||
text: <><Icons.Info /> <span>About</span></>,
|
|
||||||
onClick: () => {
|
|
||||||
app.setLocation("/about")
|
|
||||||
ActionSheetRef.current.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -91,7 +83,17 @@ const AccountButton = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class BottomBar extends React.Component {
|
export default (props) => {
|
||||||
|
return <WithPlayerContext>
|
||||||
|
<BottomBar
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</WithPlayerContext>
|
||||||
|
}
|
||||||
|
|
||||||
|
export class BottomBar extends React.Component {
|
||||||
|
static contextType = Context
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
allowed: true,
|
allowed: true,
|
||||||
show: true,
|
show: true,
|
||||||
@ -133,7 +135,7 @@ export default class BottomBar extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toggleVisibility = (to) => {
|
toggleVisibility = (to) => {
|
||||||
if (!window.isMobile) {
|
if (!app.isMobile) {
|
||||||
to = false
|
to = false
|
||||||
} else {
|
} else {
|
||||||
to = to ?? !this.state.visible
|
to = to ?? !this.state.visible
|
||||||
@ -160,21 +162,6 @@ export default class BottomBar extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderItems = () => {
|
|
||||||
return items.map((item) => {
|
|
||||||
return <div
|
|
||||||
key={item.id}
|
|
||||||
id={item.id}
|
|
||||||
className={classnames("item", ...item.classnames ?? [])}
|
|
||||||
onClick={() => this.handleItemClick(item)}
|
|
||||||
>
|
|
||||||
<div className="icon">
|
|
||||||
{createIconRender(item.icon)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (this.state.render) {
|
if (this.state.render) {
|
||||||
return <div className="bottomBar">
|
return <div className="bottomBar">
|
||||||
@ -195,7 +182,51 @@ export default class BottomBar extends React.Component {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="items">
|
<div className="items">
|
||||||
{this.renderItems()}
|
<div
|
||||||
|
key="creator"
|
||||||
|
id="creator"
|
||||||
|
className={classnames("item", "primary")}
|
||||||
|
onClick={() => app.setLocation("/")}
|
||||||
|
>
|
||||||
|
<div className="icon">
|
||||||
|
{createIconRender("PlusCircle")}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{
|
||||||
|
this.context.currentManifest && <div
|
||||||
|
className="item"
|
||||||
|
>
|
||||||
|
<PlayerButton
|
||||||
|
manifest={this.context.currentManifest}
|
||||||
|
playback={this.context.playbackStatus}
|
||||||
|
colorAnalysis={this.context.coverColorAnalysis}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
<div
|
||||||
|
key="navigator"
|
||||||
|
id="navigator"
|
||||||
|
className="item"
|
||||||
|
onClick={() => app.setLocation("/")}
|
||||||
|
>
|
||||||
|
<div className="icon">
|
||||||
|
{createIconRender("Home")}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
key="searcher"
|
||||||
|
id="searcher"
|
||||||
|
className="item"
|
||||||
|
onClick={app.controls.openSearcher}
|
||||||
|
>
|
||||||
|
<div className="icon">
|
||||||
|
{createIconRender("Search")}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<AccountButton />
|
<AccountButton />
|
||||||
</div>
|
</div>
|
||||||
</div>}
|
</div>}
|
||||||
|
@ -1,4 +1,26 @@
|
|||||||
@import "theme/vars.less";
|
@import "theme/vars.less";
|
||||||
|
@import "theme/animations.less";
|
||||||
|
|
||||||
|
.player_btn {
|
||||||
|
color: var(--color);
|
||||||
|
|
||||||
|
background-color: var(--average-color);
|
||||||
|
|
||||||
|
padding: 10px 20px;
|
||||||
|
|
||||||
|
border-radius: 8px;
|
||||||
|
|
||||||
|
&.bounce {
|
||||||
|
svg {
|
||||||
|
animation: bounce 1s infinite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
color: var(--color);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.bottomBar {
|
.bottomBar {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -24,6 +46,8 @@
|
|||||||
background-color: var(--background-color-accent);
|
background-color: var(--background-color-accent);
|
||||||
border-radius: 12px 12px 0 0;
|
border-radius: 12px 12px 0 0;
|
||||||
|
|
||||||
|
box-shadow: @card-shadow;
|
||||||
|
|
||||||
.items {
|
.items {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -227,7 +227,7 @@ export default class Login extends React.Component {
|
|||||||
>
|
>
|
||||||
<span><Icons.Lock /> Password</span>
|
<span><Icons.Lock /> Password</span>
|
||||||
<antd.Input.Password
|
<antd.Input.Password
|
||||||
placeholder="********"
|
//placeholder="********"
|
||||||
onChange={(e) => this.onUpdateInput("password", e.target.value)}
|
onChange={(e) => this.onUpdateInput("password", e.target.value)}
|
||||||
onPressEnter={this.nextStep}
|
onPressEnter={this.nextStep}
|
||||||
/>
|
/>
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
import React from "react"
|
||||||
|
import classnames from "classnames"
|
||||||
|
import * as antd from "antd"
|
||||||
|
|
||||||
|
import { createIconRender } from "components/Icons"
|
||||||
|
|
||||||
|
import "./index.less"
|
||||||
|
|
||||||
|
const NavMenu = (props) => {
|
||||||
|
const handleOnClickItem = (event) => {
|
||||||
|
return props.onClickItem(event.key)
|
||||||
|
}
|
||||||
|
|
||||||
|
return <div className="navmenu_wrapper">
|
||||||
|
{
|
||||||
|
props.header && <div className="card header" id="navMenu">
|
||||||
|
{props.header}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
<div className="card content" id="navMenu">
|
||||||
|
<antd.Menu
|
||||||
|
mode="inline"
|
||||||
|
selectedKeys={[props.activeKey]}
|
||||||
|
onClick={handleOnClickItem}
|
||||||
|
items={props.items}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
const NavMenuMobile = (props) => {
|
||||||
|
return <div className="__mobile__navmenu_wrapper">
|
||||||
|
<div className="card">
|
||||||
|
{
|
||||||
|
props.items.map((item) => {
|
||||||
|
return <div
|
||||||
|
key={item.key}
|
||||||
|
className={classnames(
|
||||||
|
"item",
|
||||||
|
item.key === props.activeKey && "active",
|
||||||
|
)}
|
||||||
|
onClick={() => props.onClickItem(item.key)}
|
||||||
|
>
|
||||||
|
<div className="icon">
|
||||||
|
{item.icon}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="label">
|
||||||
|
{item.label}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default app.isMobile ? NavMenuMobile : NavMenu
|
@ -0,0 +1,21 @@
|
|||||||
|
.navmenu_wrapper {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.__mobile__navmenu_wrapper {
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
position: sticky;
|
||||||
|
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.card {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,8 @@ import * as antd from "antd"
|
|||||||
|
|
||||||
import { createIconRender } from "components/Icons"
|
import { createIconRender } from "components/Icons"
|
||||||
|
|
||||||
|
import NavMenu from "./components/NavMenu"
|
||||||
|
|
||||||
import "./index.less"
|
import "./index.less"
|
||||||
|
|
||||||
export const Panel = (props) => {
|
export const Panel = (props) => {
|
||||||
@ -19,29 +21,6 @@ export const Panel = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
const NavMenu = (props) => {
|
|
||||||
const handleOnClickItem = (event) => {
|
|
||||||
return props.onClickItem(event.key)
|
|
||||||
}
|
|
||||||
|
|
||||||
return <div className="navmenu_wrapper">
|
|
||||||
{
|
|
||||||
props.header && <div className="card header" id="navMenu">
|
|
||||||
{props.header}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
<div className="card content" id="navMenu">
|
|
||||||
<antd.Menu
|
|
||||||
mode="inline"
|
|
||||||
selectedKeys={[props.activeKey]}
|
|
||||||
onClick={handleOnClickItem}
|
|
||||||
items={props.items}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
export class PagePanelWithNavMenu extends React.Component {
|
export class PagePanelWithNavMenu extends React.Component {
|
||||||
state = {
|
state = {
|
||||||
// if defaultTab is not set, try to get it from query, if not, use the first tab
|
// if defaultTab is not set, try to get it from query, if not, use the first tab
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
@import "theme/animations.less";
|
||||||
|
|
||||||
.background_media_player {
|
.background_media_player {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
@ -234,23 +236,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes bounce {
|
|
||||||
|
|
||||||
0%,
|
|
||||||
20%,
|
|
||||||
50%,
|
|
||||||
80%,
|
|
||||||
100% {
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
40% {
|
|
||||||
transform: translateY(-5px);
|
|
||||||
}
|
|
||||||
|
|
||||||
60% {
|
|
||||||
transform: translateY(-3px);
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -79,23 +79,25 @@ export default ({
|
|||||||
onClick={() => onClickActionsButton("next")}
|
onClick={() => onClickActionsButton("next")}
|
||||||
disabled={syncModeLocked}
|
disabled={syncModeLocked}
|
||||||
/>
|
/>
|
||||||
<antd.Popover
|
{
|
||||||
content={React.createElement(
|
!app.isMobile && <antd.Popover
|
||||||
AudioVolume,
|
content={React.createElement(
|
||||||
{ onChange: onVolumeUpdate, defaultValue: audioVolume }
|
AudioVolume,
|
||||||
)}
|
{ onChange: onVolumeUpdate, defaultValue: audioVolume }
|
||||||
trigger="hover"
|
)}
|
||||||
>
|
trigger="hover"
|
||||||
<div
|
|
||||||
className="muteButton"
|
|
||||||
onClick={onMuteUpdate}
|
|
||||||
>
|
>
|
||||||
{
|
<div
|
||||||
audioMuted
|
className="muteButton"
|
||||||
? <Icons.VolumeX />
|
onClick={onMuteUpdate}
|
||||||
: <Icons.Volume2 />
|
>
|
||||||
}
|
{
|
||||||
</div>
|
audioMuted
|
||||||
</antd.Popover>
|
? <Icons.VolumeX />
|
||||||
|
: <Icons.Volume2 />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</antd.Popover>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
@ -90,8 +90,9 @@ export class AudioPlayer extends React.Component {
|
|||||||
className={classnames(
|
className={classnames(
|
||||||
"embbededMediaPlayerWrapper",
|
"embbededMediaPlayerWrapper",
|
||||||
{
|
{
|
||||||
["hovering"]: this.state.showControls,
|
["hovering"]: this.props.frame !== false && this.state.showControls,
|
||||||
["minimized"]: this.context.minimized,
|
["minimized"]: this.context.minimized,
|
||||||
|
["no-frame"]: this.props.frame === false,
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
onMouseEnter={this.onMouse}
|
onMouseEnter={this.onMouse}
|
||||||
|
@ -18,6 +18,31 @@
|
|||||||
|
|
||||||
transition: all 150ms ease-in-out;
|
transition: all 150ms ease-in-out;
|
||||||
|
|
||||||
|
&.no-frame {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.player {
|
||||||
|
background-color: transparent;
|
||||||
|
border-radius: 0;
|
||||||
|
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top_controls {
|
||||||
|
position: relative;
|
||||||
|
opacity: 1;
|
||||||
|
|
||||||
|
height: @top_controls_height;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
background-color: transparent;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.minimized {
|
&.minimized {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
|
||||||
|
@ -98,10 +98,14 @@
|
|||||||
|
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
|
|
||||||
|
color: var(--text-color);
|
||||||
|
|
||||||
.playlistTimelineEntry_statistic {
|
.playlistTimelineEntry_statistic {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|
||||||
|
color: var(--text-color);
|
||||||
|
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
width: 35vw;
|
width: 35vw;
|
||||||
min-width: 300px;
|
min-width: 300px;
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
|
|
||||||
//max-width: 600px;
|
//max-width: 600px;
|
||||||
//min-height: 165px;
|
//min-height: 165px;
|
||||||
//height: 100%;
|
//height: 100%;
|
||||||
|
@ -368,95 +368,43 @@ export class PostsListsComponent extends React.Component {
|
|||||||
|
|
||||||
return <div className="post-list_wrapper">
|
return <div className="post-list_wrapper">
|
||||||
<LoadMore
|
<LoadMore
|
||||||
ref={this.listRef}
|
ref={this.listRef}
|
||||||
className="post-list"
|
className="post-list"
|
||||||
loadingComponent={LoadingComponent}
|
loadingComponent={LoadingComponent}
|
||||||
noResultComponent={NoResultComponent}
|
noResultComponent={NoResultComponent}
|
||||||
hasMore={this.state.hasMore}
|
hasMore={this.state.hasMore}
|
||||||
fetching={this.state.loading}
|
fetching={this.state.loading}
|
||||||
onBottom={this.onLoadMore}
|
onBottom={this.onLoadMore}
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
!this.state.realtimeUpdates && <div className="resume_btn_wrapper">
|
!this.state.realtimeUpdates && !app.isMobile && <div className="resume_btn_wrapper">
|
||||||
<antd.Button
|
<antd.Button
|
||||||
type="primary"
|
type="primary"
|
||||||
shape="round"
|
shape="round"
|
||||||
onClick={this.onResumeRealtimeUpdates}
|
onClick={this.onResumeRealtimeUpdates}
|
||||||
loading={this.state.resumingLoading}
|
loading={this.state.resumingLoading}
|
||||||
icon={<Icons.SyncOutlined />}
|
icon={<Icons.SyncOutlined />}
|
||||||
>
|
>
|
||||||
Resume
|
Resume
|
||||||
</antd.Button>
|
</antd.Button>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
this.state.list.map((data) => {
|
this.state.list.map((data) => {
|
||||||
return React.createElement(typeToComponent[data.type ?? "post"] ?? PostCard, {
|
return React.createElement(typeToComponent[data.type ?? "post"] ?? PostCard, {
|
||||||
key: data._id,
|
key: data._id,
|
||||||
data: data,
|
data: data,
|
||||||
events: {
|
events: {
|
||||||
onClickLike: this.onLikePost,
|
onClickLike: this.onLikePost,
|
||||||
onClickSave: this.onSavePost,
|
onClickSave: this.onSavePost,
|
||||||
onClickDelete: this.onDeletePost,
|
onClickDelete: this.onDeletePost,
|
||||||
onClickEdit: this.onEditPost,
|
onClickEdit: this.onEditPost,
|
||||||
}
|
}
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</LoadMore>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
return <AutoSizer
|
|
||||||
disableWidth
|
|
||||||
style={{
|
|
||||||
width: "100%",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{({ height }) => {
|
|
||||||
console.log("[PostList] AutoSizer height update => ", height)
|
|
||||||
|
|
||||||
return <LoadMore
|
|
||||||
ref={this.listRef}
|
|
||||||
contentProps={{
|
|
||||||
style: { height }
|
|
||||||
}}
|
|
||||||
className="postList"
|
|
||||||
loadingComponent={LoadingComponent}
|
|
||||||
noResultComponent={NoResultComponent}
|
|
||||||
hasMore={this.state.hasMore}
|
|
||||||
fetching={this.state.loading}
|
|
||||||
onBottom={this.onLoadMore}
|
|
||||||
>
|
|
||||||
{
|
|
||||||
!this.state.realtimeUpdates && <div className="resume_btn_wrapper">
|
|
||||||
<antd.Button
|
|
||||||
type="primary"
|
|
||||||
shape="round"
|
|
||||||
onClick={this.onResumeRealtimeUpdates}
|
|
||||||
loading={this.state.resumingLoading}
|
|
||||||
icon={<Icons.SyncOutlined />}
|
|
||||||
>
|
|
||||||
Resume
|
|
||||||
</antd.Button>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
{
|
|
||||||
this.state.list.map((data) => {
|
|
||||||
return React.createElement(typeToComponent[data.type ?? "post"] ?? PostCard, {
|
|
||||||
key: data._id,
|
|
||||||
data: data,
|
|
||||||
events: {
|
|
||||||
onClickLike: this.onLikePost,
|
|
||||||
onClickSave: this.onSavePost,
|
|
||||||
onClickDelete: this.onDeletePost,
|
|
||||||
onClickEdit: this.onEditPost,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
})
|
||||||
</LoadMore>
|
}
|
||||||
}}
|
</LoadMore>
|
||||||
</AutoSizer>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,6 @@
|
|||||||
|
|
||||||
margin: auto;
|
margin: auto;
|
||||||
z-index: 150;
|
z-index: 150;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.resume_btn_wrapper {
|
.resume_btn_wrapper {
|
||||||
|
@ -51,12 +51,8 @@ export default class Layout extends React.PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
if (window.app.cores.settings.get("forceMobileMode") || window.app.capacitor.isAppCapacitor() || Math.min(window.screen.width, window.screen.height) < 768 || navigator.userAgent.indexOf("Mobi") > -1) {
|
if (window.app.cores.settings.get("forceMobileMode") || app.isMobile) {
|
||||||
window.isMobile = true
|
|
||||||
|
|
||||||
app.layout.set("mobile")
|
app.layout.set("mobile")
|
||||||
} else {
|
|
||||||
window.isMobile = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// register events
|
// register events
|
||||||
@ -147,7 +143,7 @@ export default class Layout extends React.PureComponent {
|
|||||||
return JSON.stringify(this.state.renderError)
|
return JSON.stringify(this.state.renderError)
|
||||||
}
|
}
|
||||||
|
|
||||||
const Layout = Layouts[layoutType]
|
const Layout = Layouts[app.isMobile ? "mobile" : layoutType]
|
||||||
|
|
||||||
if (!Layout) {
|
if (!Layout) {
|
||||||
return app.eventBus.emit("runtime.crash", new Error(`Layout type [${layoutType}] not found`))
|
return app.eventBus.emit("runtime.crash", new Error(`Layout type [${layoutType}] not found`))
|
||||||
|
@ -9,11 +9,9 @@ export default (props) => {
|
|||||||
<Modal />
|
<Modal />
|
||||||
|
|
||||||
<antd.Layout.Content className={classnames("content_layout", ...props.layoutPageModesClassnames ?? [])}>
|
<antd.Layout.Content className={classnames("content_layout", ...props.layoutPageModesClassnames ?? [])}>
|
||||||
<div className={classnames("frameDecorator", "top")} />
|
|
||||||
<div id="transitionLayer" className={classnames("content_wrapper", "fade-transverse-active")}>
|
<div id="transitionLayer" className={classnames("content_wrapper", "fade-transverse-active")}>
|
||||||
{React.cloneElement(props.children, props)}
|
{React.cloneElement(props.children, props)}
|
||||||
</div>
|
</div>
|
||||||
<div className={classnames("frameDecorator", "bottom")} />
|
|
||||||
</antd.Layout.Content>
|
</antd.Layout.Content>
|
||||||
|
|
||||||
<BottomBar />
|
<BottomBar />
|
||||||
|
@ -5,7 +5,7 @@ import classnames from "classnames"
|
|||||||
import { Drawer, Sidedrawer } from "components/Layout"
|
import { Drawer, Sidedrawer } from "components/Layout"
|
||||||
|
|
||||||
export default (props) => {
|
export default (props) => {
|
||||||
return <antd.Layout className={classnames("app_layout", { ["mobile"]: window.isMobile })} style={{ height: "100%" }}>
|
return <antd.Layout className={classnames("app_layout", { ["mobile"]: app.isMobile })} style={{ height: "100%" }}>
|
||||||
<Drawer />
|
<Drawer />
|
||||||
<Sidedrawer />
|
<Sidedrawer />
|
||||||
<div id="transitionLayer" className="fade-transverse-active">
|
<div id="transitionLayer" className="fade-transverse-active">
|
||||||
|
12
packages/app/src/pages/@mobile-views/player/index.jsx
Normal file
12
packages/app/src/pages/@mobile-views/player/index.jsx
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import React from "react"
|
||||||
|
import MediaPlayer from "components/Player/MediaPlayer"
|
||||||
|
|
||||||
|
import "./index.less"
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
return <div className="__mobile-player-view">
|
||||||
|
<MediaPlayer
|
||||||
|
frame={false}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
}
|
8
packages/app/src/pages/@mobile-views/player/index.less
Normal file
8
packages/app/src/pages/@mobile-views/player/index.less
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
.__mobile-player-view {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
@ -258,7 +258,7 @@ export default class Account extends React.Component {
|
|||||||
<div className="tabMenuWrapper">
|
<div className="tabMenuWrapper">
|
||||||
<antd.Menu
|
<antd.Menu
|
||||||
className="tabMenu"
|
className="tabMenu"
|
||||||
mode={window.isMobile ? "horizontal" : "vertical"}
|
mode={app.isMobile ? "horizontal" : "vertical"}
|
||||||
selectedKeys={[this.state.tabActiveKey]}
|
selectedKeys={[this.state.tabActiveKey]}
|
||||||
onClick={(e) => this.handlePageTransition(e.key)}
|
onClick={(e) => this.handlePageTransition(e.key)}
|
||||||
>
|
>
|
||||||
|
35
packages/app/src/pages/index.mobile.jsx
Normal file
35
packages/app/src/pages/index.mobile.jsx
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import React from "react"
|
||||||
|
import * as antd from "antd"
|
||||||
|
import { Translation } from "react-i18next"
|
||||||
|
|
||||||
|
import { PagePanelWithNavMenu } from "components/PagePanels"
|
||||||
|
|
||||||
|
import { Icons } from "components/Icons"
|
||||||
|
|
||||||
|
import Tabs from "./home/tabs"
|
||||||
|
|
||||||
|
export default class Home extends React.Component {
|
||||||
|
render() {
|
||||||
|
const navMenuHeader = <>
|
||||||
|
<h1>
|
||||||
|
<Icons.Home />
|
||||||
|
<Translation>{(t) => t("Timeline")}</Translation>
|
||||||
|
</h1>
|
||||||
|
<antd.Button
|
||||||
|
type="primary"
|
||||||
|
onClick={app.controls.openPostCreator}
|
||||||
|
>
|
||||||
|
<Icons.PlusCircle />
|
||||||
|
<Translation>{(t) => t("Create")}</Translation>
|
||||||
|
</antd.Button>
|
||||||
|
</>
|
||||||
|
|
||||||
|
return <PagePanelWithNavMenu
|
||||||
|
tabs={Tabs}
|
||||||
|
navMenuHeader={navMenuHeader}
|
||||||
|
primaryPanelClassName="full"
|
||||||
|
useSetQueryType
|
||||||
|
transition
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
}
|
@ -75,7 +75,7 @@ export default (props) => {
|
|||||||
|
|
||||||
<div className="content">
|
<div className="content">
|
||||||
<div className="content_header">
|
<div className="content_header">
|
||||||
<img src={window.isMobile ? config.logo.alt : config.logo.full} className="logo" />
|
<img src={app.isMobile ? config.logo.alt : config.logo.full} className="logo" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
|
|
||||||
import "./index.less"
|
import "./index.mobile.less"
|
||||||
|
|
||||||
export default (props) => {
|
export default (props) => {
|
||||||
const [wallpaperData, setWallpaperData] = React.useState(null)
|
const [wallpaperData, setWallpaperData] = React.useState(null)
|
||||||
|
|
||||||
const setRandomWallpaper = async () => {
|
const setRandomWallpaper = async () => {
|
||||||
const featuredWallpapers = await app.cores.api.request("main", "get", "featuredWallpapers").catch((err) => {
|
const { data: featuredWallpapers } = await app.cores.api.customRequest({
|
||||||
|
method: "GET",
|
||||||
|
url: "/featured_wallpapers"
|
||||||
|
}).catch((err) => {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
return []
|
return []
|
||||||
})
|
})
|
||||||
@ -19,12 +22,12 @@ export default (props) => {
|
|||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (app.userData) {
|
if (app.userData) {
|
||||||
return app.goMain()
|
return app.navigation.goMain()
|
||||||
}
|
}
|
||||||
|
|
||||||
setRandomWallpaper()
|
setRandomWallpaper()
|
||||||
|
|
||||||
app.eventBus.emit("app.createLogin", {
|
app.controls.openLoginForm({
|
||||||
defaultLocked: true,
|
defaultLocked: true,
|
||||||
})
|
})
|
||||||
}, [])
|
}, [])
|
||||||
@ -36,9 +39,9 @@ export default (props) => {
|
|||||||
}}
|
}}
|
||||||
className="wallpaper"
|
className="wallpaper"
|
||||||
>
|
>
|
||||||
<p>
|
{/* <p>
|
||||||
{wallpaperData?.author ? wallpaperData.author : null}
|
{wallpaperData?.author ? wallpaperData.author : null}
|
||||||
</p>
|
</p> */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
22
packages/app/src/pages/login/index.mobile.less
Normal file
22
packages/app/src/pages/login/index.mobile.less
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
.loginPage {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
height: 100dvh;
|
||||||
|
|
||||||
|
.wallpaper {
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
height: 100dvh;
|
||||||
|
|
||||||
|
background-position: center;
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
}
|
@ -601,10 +601,16 @@ export default class SyncLyrics extends React.Component {
|
|||||||
colorAnalysis,
|
colorAnalysis,
|
||||||
})
|
})
|
||||||
|
|
||||||
app.SidebarController.toggleVisibility(false)
|
if (app.SidebarController) {
|
||||||
|
app.SidebarController.toggleVisibility(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (app.layout.floatingStack) {
|
||||||
|
app.layout.floatingStack.toogleGlobalVisibility(false)
|
||||||
|
}
|
||||||
|
|
||||||
app.cores.style.compactMode(true)
|
app.cores.style.compactMode(true)
|
||||||
app.cores.style.applyVariant("dark")
|
app.cores.style.applyVariant("dark")
|
||||||
app.layout.floatingStack.toogleGlobalVisibility(false)
|
|
||||||
|
|
||||||
// request full screen to browser
|
// request full screen to browser
|
||||||
if (document.fullscreenEnabled) {
|
if (document.fullscreenEnabled) {
|
||||||
@ -640,10 +646,16 @@ export default class SyncLyrics extends React.Component {
|
|||||||
|
|
||||||
delete window._hacks
|
delete window._hacks
|
||||||
|
|
||||||
app.SidebarController.toggleVisibility(true)
|
if (app.SidebarController) {
|
||||||
|
app.SidebarController.toggleVisibility(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (app.layout.floatingStack) {
|
||||||
|
app.layout.floatingStack.toogleGlobalVisibility(true)
|
||||||
|
}
|
||||||
|
|
||||||
app.cores.style.compactMode(false)
|
app.cores.style.compactMode(false)
|
||||||
app.cores.style.applyInitialVariant()
|
app.cores.style.applyInitialVariant()
|
||||||
app.layout.floatingStack.toogleGlobalVisibility(true)
|
|
||||||
|
|
||||||
// exit full screen
|
// exit full screen
|
||||||
if (document.fullscreenEnabled) {
|
if (document.fullscreenEnabled) {
|
||||||
|
@ -279,7 +279,9 @@ export default class PlaylistCreatorSteps extends React.Component {
|
|||||||
okType: "danger",
|
okType: "danger",
|
||||||
cancelText: "Cancel",
|
cancelText: "Cancel",
|
||||||
onOk: async () => {
|
onOk: async () => {
|
||||||
const result = await PlaylistModel.deletePlaylist(this.props.playlist_id)
|
const result = await PlaylistModel.deletePlaylist(this.props.playlist_id, {
|
||||||
|
remove_with_tracks: true
|
||||||
|
})
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
app.message.success("Playlist deleted")
|
app.message.success("Playlist deleted")
|
||||||
|
@ -105,7 +105,7 @@ export default (props) => {
|
|||||||
|
|
||||||
return <div
|
return <div
|
||||||
className={
|
className={
|
||||||
classnames("play", playlist.type)
|
classnames("playlist_view", playlist.type)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className="play_info_wrapper">
|
<div className="play_info_wrapper">
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.play {
|
.playlist_view {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|
||||||
grid-template-columns: 30vw 1fr;
|
grid-template-columns: 30vw 1fr;
|
||||||
@ -54,15 +54,12 @@
|
|||||||
|
|
||||||
background-color: black;
|
background-color: black;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
border-radius: 12px;
|
|
||||||
|
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -591,7 +591,7 @@ export default () => {
|
|||||||
className={classnames(
|
className={classnames(
|
||||||
"settings_wrapper",
|
"settings_wrapper",
|
||||||
{
|
{
|
||||||
["mobile"]: window.isMobile,
|
["mobile"]: app.isMobile,
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
@ -46,7 +46,7 @@ const mobileRoutes = Object.keys(pathsMobile).map((route) => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
path,
|
path,
|
||||||
element: pathsMobile[path]
|
element: pathsMobile[route]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -192,13 +192,11 @@ export const PageRender = React.memo((props) => {
|
|||||||
return <Routes>
|
return <Routes>
|
||||||
{
|
{
|
||||||
routes.map((route, index) => {
|
routes.map((route, index) => {
|
||||||
let Element = route.element
|
if (app.isMobile) {
|
||||||
|
const mobileRoute = mobileRoutes.find((r) => r.path === route.path)
|
||||||
|
|
||||||
if (window.isMobile) {
|
if (mobileRoute) {
|
||||||
const mobileElement = mobileRoutes.find((r) => r.path === route.path)
|
route = mobileRoute
|
||||||
|
|
||||||
if (mobileElement) {
|
|
||||||
Element = mobileElement
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,4 +93,23 @@
|
|||||||
to {
|
to {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes bounce {
|
||||||
|
|
||||||
|
0%,
|
||||||
|
20%,
|
||||||
|
50%,
|
||||||
|
80%,
|
||||||
|
100% {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
40% {
|
||||||
|
transform: translateY(-5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
60% {
|
||||||
|
transform: translateY(-3px);
|
||||||
|
}
|
||||||
}
|
}
|
@ -10,8 +10,10 @@
|
|||||||
.content_wrapper {
|
.content_wrapper {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
padding-top: 20px;
|
|
||||||
|
//padding-top: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content_layout {
|
.content_layout {
|
||||||
@ -22,142 +24,139 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
width: 100vw;
|
width: 100%;
|
||||||
padding: 0 10px;
|
padding: 7px;
|
||||||
|
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.frameDecorator {
|
.playlist_view {
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
|
|
||||||
z-index: 8000;
|
|
||||||
|
|
||||||
width: 100vw;
|
|
||||||
height: @app_frameDecorator_height;
|
|
||||||
|
|
||||||
background-color: rgba(var(--layoutBackgroundColor), 0.8);
|
|
||||||
|
|
||||||
filter: blur(4px);
|
|
||||||
backdrop-filter: blur(10px);
|
|
||||||
|
|
||||||
&.top {
|
|
||||||
top: 0;
|
|
||||||
transform: translate(0, -6px);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bottom {
|
|
||||||
bottom: 0;
|
|
||||||
transform: translate(0, 6px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXMETS FOR MOBILE LAYOUT
|
|
||||||
.loginPage {
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
.wallpaper {
|
|
||||||
width: 100vw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dashboard {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.postPage {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
height: 90vh;
|
.play_info_wrapper {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
.postCard {
|
.play_info {
|
||||||
&.fullmode {
|
width: 100%;
|
||||||
.wrapper {
|
|
||||||
height: 76vh;
|
|
||||||
|
|
||||||
.post_content {
|
.play_info_cover {
|
||||||
.post_attachments {
|
width: 100%;
|
||||||
height: 60vh;
|
height: 100%;
|
||||||
overflow: hidden;
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.carousel-root {
|
.list {
|
||||||
.carousel {
|
padding: 30px 10px;
|
||||||
min-height: 200px;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
>div {
|
.pagePanels {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
flex-direction: column;
|
||||||
height: 100%;
|
|
||||||
}
|
align-items: center;
|
||||||
}
|
justify-content: center;
|
||||||
}
|
|
||||||
|
overflow-x: visible;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.panel {
|
||||||
|
width: 100%;
|
||||||
|
//height: 100%;
|
||||||
|
|
||||||
|
&.left {
|
||||||
|
z-index: 500;
|
||||||
|
overflow: visible;
|
||||||
|
overflow-x: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.right {
|
||||||
|
z-index: 400;
|
||||||
|
|
||||||
|
overflow-x: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
padding: 5px;
|
||||||
|
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
box-shadow: @card-shadow;
|
||||||
|
|
||||||
|
border-radius: 12px;
|
||||||
|
|
||||||
|
isolation: unset;
|
||||||
|
overflow: visible;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
padding: 5px 10px;
|
||||||
|
|
||||||
|
border-radius: 8px;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
svg {
|
||||||
|
margin: 0 !important;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 0.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
.icon {
|
||||||
|
svg {
|
||||||
|
color: var(--colorPrimary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
color: var(--colorPrimary);
|
||||||
|
}
|
||||||
|
|
||||||
|
background-color: var(--background-color-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-list_wrapper {
|
||||||
|
.post-list {
|
||||||
|
padding-top: 10px;
|
||||||
|
border-radius: 0;
|
||||||
|
|
||||||
|
.playlistTimelineEntry {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.playlistTimelineEntry_content {
|
||||||
|
.playlistTimelineEntry_thumbnail {
|
||||||
|
img {
|
||||||
|
width: 20vw;
|
||||||
|
height: 20vw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.accountProfile {
|
.postCard {
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
.contents {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
margin-top: -4.0vh;
|
|
||||||
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
.tabContent {
|
|
||||||
padding: 0;
|
|
||||||
padding-top: 26px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tabMenuWrapper {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
margin: 0;
|
|
||||||
|
|
||||||
.ant-menu {
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.liveStream {
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
.plyr {
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
|
|
||||||
width: 100%;
|
|
||||||
height: 60vh;
|
|
||||||
|
|
||||||
border-radius: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel {
|
|
||||||
height: 40vh;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.postCard {
|
|
||||||
.post_actionsWrapper {
|
|
||||||
.actions {
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user