0.4.0a Winter
This commit is contained in:
parent
a1ff52018b
commit
c9fc7d672d
@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||

|
||||
|
||||
- Send Files Permission: Control who can send files/images in a text channel.
|
||||
![]()
|
||||

|
||||
|
||||
- Invite Page: Join a server through `acrd.app/join/<code>`.
|
||||

|
||||
|
@ -67,5 +67,5 @@ router.get('/:code/unlock', updateUser, validateUser, async (req, res) => {
|
||||
const user: SelfUserDocument = res.locals.user;
|
||||
await deps.themes.unlock(theme.id, user);
|
||||
|
||||
res.json(user.unlockedThemeIds);
|
||||
res.status(201).json(theme);
|
||||
});
|
||||
|
20
frontend/cypress.config.ts
Normal file
20
frontend/cypress.config.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { defineConfig } from 'cypress'
|
||||
|
||||
export default defineConfig({
|
||||
env: {
|
||||
baseUrl: 'http://localhost:4200',
|
||||
},
|
||||
fixturesFolder: 'e2e/fixtures',
|
||||
screenshotsFolder: 'e2e/screenshots',
|
||||
videosFolder: 'e2e/videos',
|
||||
downloadsFolder: 'e2e/downloads',
|
||||
e2e: {
|
||||
// We've imported your old cypress plugins here.
|
||||
// You may want to clean this up later by importing these.
|
||||
setupNodeEvents(on, config) {
|
||||
return require('./e2e/plugins/index.ts').default(on, config)
|
||||
},
|
||||
specPattern: 'e2e/integration/**/*.cy.{js,jsx,ts,tsx}',
|
||||
supportFile: 'e2e/support/index.ts',
|
||||
},
|
||||
})
|
@ -1,12 +0,0 @@
|
||||
{
|
||||
"env": {
|
||||
"baseUrl": "http://localhost:4200"
|
||||
},
|
||||
"fixturesFolder": "e2e/fixtures",
|
||||
"integrationFolder": "e2e/integration",
|
||||
"pluginsFile": "e2e/plugins/index.ts",
|
||||
"screenshotsFolder": "e2e/screenshots",
|
||||
"videosFolder": "e2e/videos",
|
||||
"downloadsFolder": "e2e/downloads",
|
||||
"supportFile": "e2e/support/index.ts"
|
||||
}
|
@ -16,8 +16,8 @@ export interface InputProps {
|
||||
className?: string;
|
||||
disabled?: boolean;
|
||||
tooltip?: string;
|
||||
register?: UseFormRegister<FieldValues>;
|
||||
setFocusedInputId?: (val: any) => any;
|
||||
register?: UseFormRegister<FieldValues>;
|
||||
}
|
||||
|
||||
const Input: React.FunctionComponent<InputProps & React.AllHTMLAttributes<HTMLInputElement>> = (props) => {
|
||||
|
@ -2,6 +2,7 @@ import classNames from 'classnames';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import fetchEntities from '../../../store/actions/fetch-entities';
|
||||
import { uploadFile } from '../../../store/api';
|
||||
import { createTheme, deleteTheme, getTheme, unlockTheme, updateTheme } from '../../../store/themes';
|
||||
import { openSaveChanges } from '../../../store/ui';
|
||||
@ -19,19 +20,11 @@ const UserSettingsThemes: React.FunctionComponent = () => {
|
||||
const themes = useSelector((s: Store.AppState) => s.entities.themes);
|
||||
const [themeId, setTab] = useState(selfUser.activeThemeId);
|
||||
const [addMode, enableAddMode] = useState(false);
|
||||
const [focusedInputId, setFocusedInputId] = useState('');
|
||||
|
||||
const theme = getTheme(themeId, themes);
|
||||
useEffect(() => {
|
||||
if (!theme) setTab('default');
|
||||
}, [theme, themeId]);
|
||||
useEffect(() => (!theme) && setTab('default'), [theme, themeId]);
|
||||
|
||||
const refreshFocus = () => {
|
||||
if (!focusedInputId) return;
|
||||
|
||||
const input: HTMLInputElement | null = document.querySelector(`#${focusedInputId}`);
|
||||
input?.focus();
|
||||
}
|
||||
const selfIsManager = (theme && selfUser.id == theme.creatorId);
|
||||
|
||||
const SideIcons: React.FunctionComponent = () => (
|
||||
<div className="flex items-center flex-col">
|
||||
@ -99,6 +92,7 @@ const UserSettingsThemes: React.FunctionComponent = () => {
|
||||
onClick={() => {
|
||||
enableAddMode(false);
|
||||
dispatch(unlockTheme(code, (theme) => setTab(theme.id)));
|
||||
dispatch(fetchEntities());
|
||||
}}>Add</NormalButton>
|
||||
</div>
|
||||
|
||||
@ -122,7 +116,9 @@ const UserSettingsThemes: React.FunctionComponent = () => {
|
||||
<header className="mb-5">
|
||||
<h1 className="text-3xl font-bold inline">{theme.name}</h1>
|
||||
</header>
|
||||
{/* <FileInput
|
||||
<FileInput
|
||||
disabled
|
||||
// disabled={true}!selfIsManager}
|
||||
className="w-1/3"
|
||||
name="icon"
|
||||
label="Icon"
|
||||
@ -135,26 +131,28 @@ const UserSettingsThemes: React.FunctionComponent = () => {
|
||||
dispatch(uploadFile(file, ({ url }) => {
|
||||
dispatch(updateTheme(themeId, { iconURL: url }));
|
||||
}));
|
||||
}} /> */}
|
||||
}} />
|
||||
|
||||
<form
|
||||
onChange={() => dispatch(openSaveChanges(true))}
|
||||
className="flex flex-col h-full mt-1 mb-5">
|
||||
<div className="flex">
|
||||
<Input
|
||||
disabled={!selfIsManager}
|
||||
className="w-1/3 mr-5"
|
||||
label="Name"
|
||||
name="name"
|
||||
register={register}
|
||||
options={{ value: theme.name }} />
|
||||
<Input
|
||||
disabled
|
||||
// disabled={!selfIsManager}
|
||||
tooltip="The code that is used to share themes."
|
||||
className="w-1/3 mr-5"
|
||||
label="Code"
|
||||
name="code"
|
||||
register={register}
|
||||
options={{ value: theme.code }}
|
||||
disabled />
|
||||
options={{ value: theme.code }} />
|
||||
</div>
|
||||
|
||||
<div className='mt-2'>
|
||||
@ -164,28 +162,27 @@ const UserSettingsThemes: React.FunctionComponent = () => {
|
||||
|
||||
<textarea
|
||||
id="styles"
|
||||
disabled={!selfIsManager}
|
||||
rows={20}
|
||||
className="p-2 rounded bg-bg-secondary outline-none w-full mt-2"
|
||||
defaultValue={theme.styles}
|
||||
onFocus={(e) => setFocusedInputId?.(e.currentTarget.id)}
|
||||
{...register('styles', { value: theme.styles })} />
|
||||
</div>
|
||||
|
||||
<SaveChanges
|
||||
onOpen={refreshFocus}
|
||||
setValue={setValue}
|
||||
onSave={onSave}
|
||||
obj={theme} />
|
||||
</form>
|
||||
|
||||
<NormalButton
|
||||
className="bg-success dark mt-5"
|
||||
onClick={onApply}>Apply</NormalButton>
|
||||
{(selfUser.id === theme.creatorId) && (
|
||||
{(selfIsManager) && (
|
||||
<NormalButton
|
||||
className="bg-danger dark mt-5 ml-2"
|
||||
onClick={onDelete}>Delete</NormalButton>
|
||||
)}
|
||||
|
||||
<SaveChanges
|
||||
setValue={setValue}
|
||||
onSave={onSave}
|
||||
obj={theme} />
|
||||
</div>
|
||||
) : null;
|
||||
}
|
||||
|
@ -6,5 +6,6 @@ export const filterProps = (props: object) => {
|
||||
register: undefined,
|
||||
titleName: undefined,
|
||||
initialValue: undefined,
|
||||
setfocusedinputid: undefined,
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
@import './styles/theme/theme-util.css';
|
||||
@import './styles/theme/accord-theme.css';
|
||||
@import './styles/output.css';
|
||||
@import '~@fortawesome/fontawesome-svg-core/styles.css';
|
||||
|
||||
|
@ -77,7 +77,10 @@ export const unlockTheme = (id: string, callback?: (theme: Entity.Theme) => any)
|
||||
dispatch(api.restCallBegan({
|
||||
url: `/themes/${id}/unlock`,
|
||||
headers: getHeaders(),
|
||||
callback,
|
||||
callback: (theme: Entity.Theme) => {
|
||||
dispatch(actions.fetched([theme]))
|
||||
callback(theme);
|
||||
},
|
||||
}));
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user