mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-09 10:34:17 +00:00
improve settings desing
This commit is contained in:
parent
1e23aad5b4
commit
4a38afb45a
@ -1,20 +1,20 @@
|
|||||||
{
|
{
|
||||||
"app": {
|
"app": {
|
||||||
"label": "Application Settings"
|
"label": "Application"
|
||||||
},
|
},
|
||||||
"basic": {
|
"basic": {
|
||||||
"label": "Basic Settings"
|
"label": "Basic"
|
||||||
},
|
},
|
||||||
"security": {
|
"security": {
|
||||||
"label": "Security Settings"
|
"label": "Security"
|
||||||
},
|
},
|
||||||
"privacy": {
|
"privacy": {
|
||||||
"label": "Privacy Settings"
|
"label": "Privacy"
|
||||||
},
|
},
|
||||||
"advanced": {
|
"advanced": {
|
||||||
"label": "Advanced Settings"
|
"label": "Advanced"
|
||||||
},
|
},
|
||||||
"other": {
|
"other": {
|
||||||
"label": "Other Settings"
|
"label": "Other"
|
||||||
}
|
}
|
||||||
}
|
}
|
70
packages/app/src/components/UserShareBadge/index.jsx
Normal file
70
packages/app/src/components/UserShareBadge/index.jsx
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import React from "react"
|
||||||
|
import * as antd from "antd"
|
||||||
|
|
||||||
|
import Image from "@components/Image"
|
||||||
|
import UserBadges from "@components/UserBadges"
|
||||||
|
import { Icons, createIconRender } from "@components/Icons"
|
||||||
|
|
||||||
|
import ContrastYIQ from "@utils/contrastYIQ"
|
||||||
|
|
||||||
|
import "./index.less"
|
||||||
|
|
||||||
|
const UserShareBadge = (props) => {
|
||||||
|
const { user } = props
|
||||||
|
|
||||||
|
const [loading, setLoading] = React.useState(true)
|
||||||
|
const [contrastColor, setContrastColor] = React.useState(null)
|
||||||
|
|
||||||
|
async function initialize(params) {
|
||||||
|
setLoading(true)
|
||||||
|
|
||||||
|
const contrastYIQ = await ContrastYIQ.fromUrl(user.cover)
|
||||||
|
|
||||||
|
setContrastColor(contrastYIQ)
|
||||||
|
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
initialize()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return <div className="user-share-badge">
|
||||||
|
<antd.Skeleton active />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
return <div
|
||||||
|
className="user-share-badge"
|
||||||
|
style={{
|
||||||
|
backgroundImage: `url("${user.cover}")`,
|
||||||
|
color: contrastColor
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="user-share-badge-info">
|
||||||
|
<div className="user-share-badge-avatar">
|
||||||
|
<Image
|
||||||
|
src={user.avatar}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="user-share-badge-username">
|
||||||
|
<h1>
|
||||||
|
{user.public_name || user.username}
|
||||||
|
{user.verified && <Icons.verifiedBadge />}
|
||||||
|
</h1>
|
||||||
|
<span>
|
||||||
|
@{user.username}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{
|
||||||
|
user.badges?.length > 0 && <UserBadges user_id={user._id} />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default UserShareBadge
|
60
packages/app/src/components/UserShareBadge/index.less
Normal file
60
packages/app/src/components/UserShareBadge/index.less
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
.user-share-badge {
|
||||||
|
width: 400px;
|
||||||
|
height: 240px;
|
||||||
|
|
||||||
|
border-radius: 24px;
|
||||||
|
|
||||||
|
// background-color: rgb(255, 96, 100);
|
||||||
|
// background-image: radial-gradient(circle, currentcolor 0%, transparent 110%);
|
||||||
|
|
||||||
|
outline: 2px solid var(--border-color);
|
||||||
|
|
||||||
|
padding: 20px;
|
||||||
|
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: cover;
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6,
|
||||||
|
p,
|
||||||
|
span {
|
||||||
|
color: currentColor;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-share-badge-info {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
backdrop-filter: blur(5px);
|
||||||
|
-webkit-backdrop-filter: blur(5px);
|
||||||
|
|
||||||
|
background-color: rgba(var(--bg_color_4), 0.4);
|
||||||
|
|
||||||
|
width: fit-content;
|
||||||
|
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 12px;
|
||||||
|
|
||||||
|
.user-share-badge-avatar {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
img {
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-share-badge-username {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
font-size: 1.3rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -360,6 +360,14 @@ export default class SettingItemComponent extends React.PureComponent {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
computeSwitchEnablerDefault = () => {
|
||||||
|
if (typeof this.props.setting.switchDefault === "function") {
|
||||||
|
return this.props.setting.switchDefault()
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.props.setting.switchDefault
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (!this.props.setting) {
|
if (!this.props.setting) {
|
||||||
console.error(`Item [${this.props.setting.id}] has no an setting!`)
|
console.error(`Item [${this.props.setting.id}] has no an setting!`)
|
||||||
@ -428,8 +436,9 @@ export default class SettingItemComponent extends React.PureComponent {
|
|||||||
{(t) => t(this.props.setting.title ?? this.props.setting.id)}
|
{(t) => t(this.props.setting.title ?? this.props.setting.id)}
|
||||||
</Translation>
|
</Translation>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
{
|
{
|
||||||
this.props.setting.experimental && <antd.Tag> Experimental </antd.Tag>
|
this.props.setting.experimental && <antd.Tag>Experimental</antd.Tag>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div className="setting_item_header_description">
|
<div className="setting_item_header_description">
|
||||||
@ -441,45 +450,50 @@ export default class SettingItemComponent extends React.PureComponent {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{
|
<div className="setting_item_header_actions">
|
||||||
this.props.setting.extraActions && <div className="setting_item_header_actions">
|
{
|
||||||
{
|
this.props.setting.extraActions && this.props.setting.extraActions.map((action, index) => {
|
||||||
this.props.setting.extraActions.map((action, index) => {
|
if (typeof action === "function") {
|
||||||
if (typeof action === "function") {
|
return React.createElement(action, {
|
||||||
return React.createElement(action, {
|
ctx: {
|
||||||
ctx: {
|
updateCurrentValue: (updateValue) => this.setState({
|
||||||
updateCurrentValue: (updateValue) => this.setState({
|
value: updateValue
|
||||||
value: updateValue
|
}),
|
||||||
}),
|
getCurrentValue: () => this.state.value,
|
||||||
getCurrentValue: () => this.state.value,
|
currentValue: this.state.value,
|
||||||
currentValue: this.state.value,
|
dispatchUpdate: this.dispatchUpdate,
|
||||||
dispatchUpdate: this.dispatchUpdate,
|
onUpdateItem: this.onUpdateItem,
|
||||||
onUpdateItem: this.onUpdateItem,
|
processedCtx: this.props.ctx
|
||||||
processedCtx: this.props.ctx
|
},
|
||||||
},
|
})
|
||||||
})
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const handleOnClick = () => {
|
const handleOnClick = () => {
|
||||||
if (action.onClick) {
|
if (action.onClick) {
|
||||||
action.onClick(finalProps.ctx)
|
action.onClick(finalProps.ctx)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return <antd.Button
|
return <antd.Button
|
||||||
key={action.id}
|
key={action.id}
|
||||||
id={action.id}
|
id={action.id}
|
||||||
onClick={handleOnClick}
|
onClick={handleOnClick}
|
||||||
icon={action.icon && createIconRender(action.icon)}
|
icon={action.icon && createIconRender(action.icon)}
|
||||||
type={action.type ?? "round"}
|
type={action.type ?? "round"}
|
||||||
disabled={this.props.setting.disabled}
|
disabled={this.props.setting.disabled}
|
||||||
>
|
>
|
||||||
{action.title}
|
{action.title}
|
||||||
</antd.Button>
|
</antd.Button>
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</div>
|
|
||||||
}
|
{
|
||||||
|
typeof this.props.setting.onEnabledChange === "function" && <antd.Switch
|
||||||
|
defaultChecked={this.computeSwitchEnablerDefault()}
|
||||||
|
onChange={this.props.setting.onEnabledChange}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="setting_item_content">
|
<div className="setting_item_content">
|
||||||
|
@ -45,12 +45,13 @@
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
color: var(--background-color-contrast);
|
color: var(--background-color-contrast);
|
||||||
|
|
||||||
|
gap: 5px;
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -55,7 +55,7 @@ const generateMenuItems = () => {
|
|||||||
return {
|
return {
|
||||||
key: item.id,
|
key: item.id,
|
||||||
type: "item",
|
type: "item",
|
||||||
label: <div {...item.props}>
|
label: <div {...item.props} className="menu-item-content">
|
||||||
{createIconRender(item.icon ?? "Settings")}
|
{createIconRender(item.icon ?? "Settings")}
|
||||||
{item.label}
|
{item.label}
|
||||||
</div>,
|
</div>,
|
||||||
@ -126,7 +126,9 @@ export default () => {
|
|||||||
if (app.layout.tools_bar) {
|
if (app.layout.tools_bar) {
|
||||||
app.layout.tools_bar.toggleVisibility(false)
|
app.layout.tools_bar.toggleVisibility(false)
|
||||||
}
|
}
|
||||||
|
}, [activeKey])
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
if (app.layout.tools_bar) {
|
if (app.layout.tools_bar) {
|
||||||
app.layout.tools_bar.toggleVisibility(true)
|
app.layout.tools_bar.toggleVisibility(true)
|
||||||
|
@ -29,6 +29,43 @@
|
|||||||
|
|
||||||
padding: 0 30px;
|
padding: 0 30px;
|
||||||
|
|
||||||
|
gap: 3px;
|
||||||
|
|
||||||
|
.ant-menu-item-group-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
gap: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
height: fit-content;
|
||||||
|
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-menu-item {
|
||||||
|
padding: 0 !important;
|
||||||
|
padding-inline: 20px !important;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
border-radius: 24px;
|
||||||
|
|
||||||
|
.ant-menu-title-content {
|
||||||
|
height: fit-content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.ant-menu-item-danger {
|
.ant-menu-item-danger {
|
||||||
.ant-menu-title-content {
|
.ant-menu-title-content {
|
||||||
svg {
|
svg {
|
||||||
@ -59,7 +96,7 @@
|
|||||||
|
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
|
|
||||||
padding: 20px;
|
padding: 15px;
|
||||||
|
|
||||||
gap: 15px;
|
gap: 15px;
|
||||||
|
|
||||||
|
@ -78,6 +78,10 @@ export default {
|
|||||||
width: "100%"
|
width: "100%"
|
||||||
},
|
},
|
||||||
options: [
|
options: [
|
||||||
|
{
|
||||||
|
label: "Noto Sans",
|
||||||
|
value: "'Noto Sans', sans-serif"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: "Inter (Default)",
|
label: "Inter (Default)",
|
||||||
value: "'Inter', sans-serif"
|
value: "'Inter', sans-serif"
|
||||||
@ -117,7 +121,7 @@ export default {
|
|||||||
},
|
},
|
||||||
storaged: false,
|
storaged: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
id: "style.backgroundImage",
|
id: "style.backgroundImage",
|
||||||
group: "aspect",
|
group: "aspect",
|
||||||
|
@ -88,41 +88,75 @@ export default (props) => {
|
|||||||
}, [selectedPreset])
|
}, [selectedPreset])
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "inline-flex",
|
|
||||||
alignItems: "center",
|
|
||||||
gap: "5px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Icons.MdList
|
|
||||||
style={{
|
|
||||||
margin: "0"
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Select
|
|
||||||
style={{
|
|
||||||
width: "50%"
|
|
||||||
}}
|
|
||||||
value={selectedPreset}
|
|
||||||
options={options}
|
|
||||||
onChange={(key) => {
|
|
||||||
if (key === "new") {
|
|
||||||
handleCreateNewPreset()
|
|
||||||
} else {
|
|
||||||
setSelectedPreset(key)
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
onClick={handleDeletePreset}
|
|
||||||
icon={<Icons.MdDelete />}
|
|
||||||
disabled={selectedPreset === "default"}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Sliders
|
<Sliders
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "inline-flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
alignItems: "center",
|
||||||
|
gap: "5px",
|
||||||
|
width: "100%",
|
||||||
|
backgroundColor: "rgba(var(--bg_color_3), 0.5)",
|
||||||
|
padding: "5px 10px",
|
||||||
|
borderRadius: "12px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "inline-flex",
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
gap: "5px",
|
||||||
|
width: "100%",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Icons.MdList
|
||||||
|
style={{
|
||||||
|
margin: "0"
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<h4
|
||||||
|
style={{
|
||||||
|
margin: "0",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
|
||||||
|
Preset
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "inline-flex",
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
gap: "5px",
|
||||||
|
width: "100%",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Select
|
||||||
|
style={{
|
||||||
|
width: "50%"
|
||||||
|
}}
|
||||||
|
value={selectedPreset}
|
||||||
|
options={options}
|
||||||
|
onChange={(key) => {
|
||||||
|
if (key === "new") {
|
||||||
|
handleCreateNewPreset()
|
||||||
|
} else {
|
||||||
|
setSelectedPreset(key)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
onClick={handleDeletePreset}
|
||||||
|
icon={<Icons.MdDelete />}
|
||||||
|
disabled={selectedPreset === "default"}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
@ -7,14 +7,14 @@ import WidgetItemPreview from "@components/WidgetItemPreview"
|
|||||||
|
|
||||||
import "./index.less"
|
import "./index.less"
|
||||||
|
|
||||||
export default class WidgetsView extends React.Component {
|
export default class WidgetsManager extends React.Component {
|
||||||
state = {
|
state = {
|
||||||
loadedWidgets: this.props.ctx.currentValue ?? [],
|
loadedWidgets: app.cores.widgets.getInstalled() ?? [],
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <div className="widgets_load">
|
return <div className="widgets-manager">
|
||||||
<div className="widgets_load_list">
|
<div className="widgets-manager-list">
|
||||||
{
|
{
|
||||||
Array.isArray(this.state.loadedWidgets) && this.state.loadedWidgets.map((manifest) => {
|
Array.isArray(this.state.loadedWidgets) && this.state.loadedWidgets.map((manifest) => {
|
||||||
return <React.Fragment>
|
return <React.Fragment>
|
||||||
@ -52,7 +52,7 @@ export default class WidgetsView extends React.Component {
|
|||||||
icon={<Icons.Plus />}
|
icon={<Icons.Plus />}
|
||||||
onClick={openWidgetsBrowserModal}
|
onClick={openWidgetsBrowserModal}
|
||||||
>
|
>
|
||||||
Add widget
|
Install more
|
||||||
</antd.Button>
|
</antd.Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -1,16 +1,16 @@
|
|||||||
.widgets_load {
|
.widgets-manager {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
|
|
||||||
.widgets_load_list {
|
.widgets-manager-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
|
|
||||||
.widget_load_list_item {
|
.widgets-manager-list-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|
||||||
@ -22,14 +22,14 @@
|
|||||||
border: 1px var(--border-color) solid;
|
border: 1px var(--border-color) solid;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
|
|
||||||
.widget_load_list_item_info {
|
.widgets-manager-list-item-info {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.widget_load_list_item_icon {
|
.widgets-manager-list-item-icon {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|
||||||
@ -47,7 +47,6 @@
|
|||||||
|
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -7,17 +7,35 @@ export default {
|
|||||||
group: "app",
|
group: "app",
|
||||||
settings: [
|
settings: [
|
||||||
{
|
{
|
||||||
id: "player.allowVolumeOver100",
|
id: "player.gain",
|
||||||
title: "Allow volume over 100%",
|
title: "Gain",
|
||||||
|
icon: "MdGraphicEq",
|
||||||
group: "general",
|
group: "general",
|
||||||
icon: "MdHearing",
|
description: "Adjust gain for audio output",
|
||||||
description: "Allow volume amplification over 100% (may cause distortion)",
|
component: "Slider",
|
||||||
component: "Switch",
|
props: {
|
||||||
storaged: true,
|
min: 1,
|
||||||
|
max: 2,
|
||||||
|
step: 0.1,
|
||||||
|
marks: {
|
||||||
|
1: "Normal",
|
||||||
|
1.5: "+50%",
|
||||||
|
2: "+100%"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
defaultValue: () => {
|
||||||
|
return app.cores.player.gain.values().gain
|
||||||
|
},
|
||||||
|
onUpdate: (value) => {
|
||||||
|
app.cores.player.gain.modifyValues({
|
||||||
|
gain: value
|
||||||
|
})
|
||||||
|
},
|
||||||
|
storaged: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "player.sample_rate",
|
id: "player.sample_rate",
|
||||||
title: "Sample rate",
|
title: "Sample Rate",
|
||||||
icon: "MdHearing",
|
icon: "MdHearing",
|
||||||
group: "general",
|
group: "general",
|
||||||
description: "Internal sample rate for audio output",
|
description: "Internal sample rate for audio output",
|
||||||
@ -52,54 +70,9 @@ export default {
|
|||||||
},
|
},
|
||||||
storaged: false,
|
storaged: false,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: "player.crossfade",
|
|
||||||
title: "Crossfade",
|
|
||||||
icon: "MdSwapHoriz",
|
|
||||||
group: "general",
|
|
||||||
description: "Enable crossfade between tracks",
|
|
||||||
component: "Slider",
|
|
||||||
props: {
|
|
||||||
min: 0,
|
|
||||||
max: 10,
|
|
||||||
step: 0.1,
|
|
||||||
marks: {
|
|
||||||
0: "Off",
|
|
||||||
1: "1s",
|
|
||||||
2: "2s",
|
|
||||||
3: "3s",
|
|
||||||
4: "4s",
|
|
||||||
5: "5s",
|
|
||||||
6: "6s",
|
|
||||||
7: "7s",
|
|
||||||
8: "8s",
|
|
||||||
9: "9s",
|
|
||||||
10: "10s",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
storaged: true,
|
|
||||||
disabled: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "player.compressor",
|
|
||||||
title: "Compression",
|
|
||||||
icon: "MdGraphicEq",
|
|
||||||
group: "general",
|
|
||||||
description: "Enable compression for audio output",
|
|
||||||
component: "Switch",
|
|
||||||
experimental: true,
|
|
||||||
beforeSave: (value) => {
|
|
||||||
if (value) {
|
|
||||||
app.cores.player.compressor.attach()
|
|
||||||
} else {
|
|
||||||
app.cores.player.compressor.detach()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
storaged: true,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: "player.compressor.values",
|
id: "player.compressor.values",
|
||||||
title: "Compression adjustment",
|
title: "Compression",
|
||||||
icon: "Sliders",
|
icon: "Sliders",
|
||||||
group: "general",
|
group: "general",
|
||||||
description: "Adjust compression values (Warning: may cause distortion when changing values)",
|
description: "Adjust compression values (Warning: may cause distortion when changing values)",
|
||||||
@ -108,6 +81,18 @@ export default {
|
|||||||
"player.compressor": true
|
"player.compressor": true
|
||||||
},
|
},
|
||||||
component: loadable(() => import("./items/player.compressor")),
|
component: loadable(() => import("./items/player.compressor")),
|
||||||
|
switchDefault: () => {
|
||||||
|
return app.cores.settings.get("player.compressor")
|
||||||
|
},
|
||||||
|
onEnabledChange: (enabled) => {
|
||||||
|
if (enabled === true) {
|
||||||
|
app.cores.settings.set("player.compressor", true)
|
||||||
|
app.cores.player.compressor.attach()
|
||||||
|
} else {
|
||||||
|
app.cores.settings.set("player.compressor", false)
|
||||||
|
app.cores.player.compressor.detach()
|
||||||
|
}
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
valueFormat: (value) => `${value}dB`,
|
valueFormat: (value) => `${value}dB`,
|
||||||
sliders: [
|
sliders: [
|
||||||
@ -149,7 +134,7 @@ export default {
|
|||||||
extraActions: [
|
extraActions: [
|
||||||
{
|
{
|
||||||
id: "reset",
|
id: "reset",
|
||||||
title: "Reset",
|
title: "Default",
|
||||||
icon: "MdRefresh",
|
icon: "MdRefresh",
|
||||||
onClick: async (ctx) => {
|
onClick: async (ctx) => {
|
||||||
const values = await app.cores.player.compressor.resetDefaultValues()
|
const values = await app.cores.player.compressor.resetDefaultValues()
|
||||||
@ -165,33 +150,7 @@ export default {
|
|||||||
},
|
},
|
||||||
storaged: false,
|
storaged: false,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: "player.gain",
|
|
||||||
title: "Gain",
|
|
||||||
icon: "MdGraphicEq",
|
|
||||||
group: "general",
|
|
||||||
description: "Adjust gain for audio output",
|
|
||||||
component: "Slider",
|
|
||||||
props: {
|
|
||||||
min: 1,
|
|
||||||
max: 2,
|
|
||||||
step: 0.1,
|
|
||||||
marks: {
|
|
||||||
1: "Off",
|
|
||||||
1.5: "50%",
|
|
||||||
2: "100%"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
defaultValue: () => {
|
|
||||||
return app.cores.player.gain.values().gain
|
|
||||||
},
|
|
||||||
onUpdate: (value) => {
|
|
||||||
app.cores.player.gain.modifyValues({
|
|
||||||
gain: value
|
|
||||||
})
|
|
||||||
},
|
|
||||||
storaged: false,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: "player.eq",
|
id: "player.eq",
|
||||||
title: "Equalizer",
|
title: "Equalizer",
|
||||||
@ -211,7 +170,9 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
usePadding: false,
|
dependsOn: {
|
||||||
|
"player.equalizer": true
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
valueFormat: (value) => `${value}dB`,
|
valueFormat: (value) => `${value}dB`,
|
||||||
marks: [
|
marks: [
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
|
import { Switch } from "antd"
|
||||||
import SlidersWithPresets from "../../../components/slidersWithPresets"
|
import SlidersWithPresets from "../../../components/slidersWithPresets"
|
||||||
|
|
||||||
export default (props) => {
|
export default (props) => {
|
||||||
return <SlidersWithPresets
|
return <SlidersWithPresets
|
||||||
{...props}
|
{...props}
|
||||||
controller={app.cores.player.compressor}
|
controller={app.cores.player.compressor}
|
||||||
|
extraHeaderItems={[
|
||||||
|
<Switch
|
||||||
|
onChange={props.onEnabledChange}
|
||||||
|
/>
|
||||||
|
]}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
@ -3,15 +3,16 @@ import * as antd from "antd"
|
|||||||
import classnames from "classnames"
|
import classnames from "classnames"
|
||||||
import NFCModel from "comty.js/models/nfc"
|
import NFCModel from "comty.js/models/nfc"
|
||||||
|
|
||||||
import StepsContext from "./context"
|
|
||||||
|
|
||||||
import { Icons } from "@components/Icons"
|
import { Icons } from "@components/Icons"
|
||||||
|
import UserShareBadge from "@components/UserShareBadge"
|
||||||
|
|
||||||
import CheckRegister from "./steps/check_register"
|
import CheckRegister from "./steps/check_register"
|
||||||
import DataEditor from "./steps/data_editor"
|
import DataEditor from "./steps/data_editor"
|
||||||
import TagWritter from "./steps/tag_writter"
|
import TagWritter from "./steps/tag_writter"
|
||||||
import Success from "./steps/success"
|
import Success from "./steps/success"
|
||||||
|
|
||||||
|
import StepsContext from "./context"
|
||||||
|
|
||||||
import "./index.less"
|
import "./index.less"
|
||||||
|
|
||||||
const RegisterNewTagSteps = [
|
const RegisterNewTagSteps = [
|
||||||
@ -306,14 +307,29 @@ const TapShareRender = () => {
|
|||||||
<Icons.MdSpoke /> Registered Tags
|
<Icons.MdSpoke /> Registered Tags
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{
|
{
|
||||||
app.cores.nfc.scanning && <span className="tip">
|
app.cores.nfc.scanning && <span className="tip">
|
||||||
<Icons.MdInfo /> You can quickly edit your tags by tapping them.
|
<Icons.MdInfo /> You can quickly edit your tags by tapping them.
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
|
|
||||||
<OwnTags />
|
<OwnTags />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="tap-share-field">
|
||||||
|
<div className="tap-share-field_header">
|
||||||
|
<h1>
|
||||||
|
<Icons.MdBadge /> Your Badge
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<UserShareBadge
|
||||||
|
user={app.userData}
|
||||||
|
editMode
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
{
|
{
|
||||||
app.isMobile && <antd.Button
|
app.isMobile && <antd.Button
|
||||||
type="primary"
|
type="primary"
|
||||||
|
@ -1,26 +1,23 @@
|
|||||||
import loadable from "@loadable/component"
|
import React from "react"
|
||||||
|
|
||||||
|
import WidgetsManager from "../components/widgetsManager"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
id: "widgets",
|
id: "widgets",
|
||||||
icon: "List",
|
icon: "List",
|
||||||
label: "Widgets",
|
label: "Widgets",
|
||||||
group: "app",
|
group: "app",
|
||||||
settings: [
|
render: () => {
|
||||||
{
|
React.useEffect(() => {
|
||||||
id: "widgets.urls",
|
if (app.layout.tools_bar) {
|
||||||
title: "Widgets",
|
app.layout.tools_bar.toggleVisibility(true)
|
||||||
group: "general",
|
}
|
||||||
icon: "List",
|
}, [])
|
||||||
component: loadable(() => import("../components/widgetsView")),
|
|
||||||
defaultValue: () => {
|
|
||||||
if (typeof app.cores.widgets === "undefined") {
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
|
|
||||||
return app.cores.widgets.getInstalled()
|
return <div>
|
||||||
},
|
<h1>Widgets</h1>
|
||||||
reloadValueOnUpdateEvent: "widgets:update",
|
|
||||||
storaged: false,
|
<WidgetsManager />
|
||||||
}
|
</div>
|
||||||
]
|
},
|
||||||
}
|
}
|
@ -1,6 +1,7 @@
|
|||||||
/* Selectable fonts for users */
|
/* Selectable fonts for users */
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap');
|
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap');
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Varela+Round&display=swap');
|
@import url('https://fonts.googleapis.com/css2?family=Varela+Round&display=swap');
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,100..900;1,100..900&display=swap');
|
||||||
|
|
||||||
/* Required secondary fonts */
|
/* Required secondary fonts */
|
||||||
@import url('https://fonts.googleapis.com/css2?family=DM+Mono:ital,wght@0,300;0,400;0,500;1,300;1,400;1,500&display=swap');
|
@import url('https://fonts.googleapis.com/css2?family=DM+Mono:ital,wght@0,300;0,400;0,500;1,300;1,400;1,500&display=swap');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user