Add error message for missing uploads folder.

This commit is contained in:
theADAMJR 2023-05-30 23:01:43 +01:00
parent 01e0d7d454
commit d0acf2fe7a
13 changed files with 92 additions and 49 deletions

View File

@ -32,7 +32,11 @@ Built with React, TypeScript, and Node.js.
cd frontend && npm i -f
cd ../backend && npm i -f
```
4. In `backend` directory, configure `.env.example` and rename the file to `.env`
4. Add upload folder.
```
mkdir -p assets/upload
```
5. In `backend` directory, configure `.env.example` and rename the file to `.env`
---

View File

@ -6,8 +6,8 @@ import { parse } from 'yaml';
import fs from 'fs';
global['config'] = parse(fs.readFileSync('../config.yaml', 'utf-8'));
import './modules/deps';
import './modules/logger';
import './modules/deps';
import { User } from './data/models/user';
connect(process.env.MONGO_URI, {

View File

@ -22,7 +22,9 @@ function setupMulter(app: Application) {
const uploadDir = resolve('./assets/upload');
try {
execSync(`mkdir -p ${uploadDir} 2>> /dev/null`);
} catch { }
} catch {
log.error("Upload folder not created. Refer to the setup guide.");
}
// uses storage rather than memory - 2 file operations per file upload
const storage = multer.diskStorage({

View File

@ -23,7 +23,7 @@ const MessageHeader: FunctionComponent<MessageHeaderProps> = ({ author, message,
<ContextMenuTrigger id={author.id}>
<span
style={{ color: highestRole?.color ?? 'var(--font)' }}
className="text-base heading hover:underline cursor-pointer mr-2">{author.username}</span>
className="context-menu text-base heading hover:underline cursor-pointer mr-2">{author.username}</span>
</ContextMenuTrigger>
<span className="text-xs muted">
<MessageTimestamp message={message} />

View File

@ -76,7 +76,7 @@ const Message: React.FunctionComponent<MessageProps> = ({ message }: MessageProp
return (
<ContextMenuTrigger key={message.id} id={message.id}>
<div className={classNames('message flex', { 'mt-4': !isActuallyExtra })}>
<div className={classNames('context-menu message flex', { 'mt-4': !isActuallyExtra })}>
<div className="flex-shrink-0 left-side text-xs w-16 mr-2 pl-5 pt-1"><LeftSide /></div>
<div className="relative flex-grow px-2">
<div className="absolute toolbar right-0 -mt-3 z-10">

View File

@ -79,12 +79,14 @@ const ChannelSettingsPerms: React.FunctionComponent = () => {
<nav className="pr-10">
{overrideRoles.reverse().map(r => (
<ContextMenuTrigger id={r.id} key={r.id}>
<TabLink
style={{ color: r.color }}
tab={roleId}
setTab={setRoleId}
id={r.id}>{r.name}</TabLink>
<RoleMenu role={r} />
<div className="context-menu">
<TabLink
style={{ color: r.color }}
tab={roleId}
setTab={setRoleId}
id={r.id}>{r.name}</TabLink>
<RoleMenu role={r} />
</div>
</ContextMenuTrigger>
))}

View File

@ -99,7 +99,7 @@ const GuildSettingsRoles: React.FunctionComponent = () => {
<ContextMenuTrigger id={r.id} key={r.id}>
<TabLink
className={classNames({
'cursor-not-allowed opacity-25': !selfIsHigher(r),
'context-menu cursor-not-allowed opacity-25': !selfIsHigher(r),
})}
key={r.id}
style={{ color: r.color }}

View File

@ -59,7 +59,7 @@ const UserSettingsThemes: React.FunctionComponent = () => {
const ThemeDetails: React.FunctionComponent = () => {
const { register, setValue, handleSubmit } = useForm();
const theme = themes.find(t => t.id === themeId);
const creatorUser: Entity.User = useSelector(getUser(theme?.creatorId));
const creatorUser: Entity.User = useSelector(getUser(theme.creatorId));
if (!theme) return null;
const onApply = () => dispatch(updateSelf({ activeThemeId: themeId }));

View File

@ -41,7 +41,7 @@ const ChannelTabs: React.FunctionComponent = () => {
return <div className="p-2 pl-3">{users.map(u =>
<ContextMenuTrigger key={u.id} id={u.id}>
<div className="mb-1">
<div className="context-menu mb-1">
<FoundUsername user={u} size="sm" guild={activeGuild} />
</div>
</ContextMenuTrigger>
@ -69,25 +69,27 @@ const ChannelTabs: React.FunctionComponent = () => {
return (
<>
<ContextMenuTrigger key={channel.id} id={channel.id}>
{/* <Draggable> */}
<Link
onClick={onClick}
to={link}
className={classNames(
`cursor-pointer flex items-center rounded h-8 p-2 pl-3`,
{ active: channel.id === activeChannel?.id },
)}>
<FontAwesomeIcon
size="xs"
<div className='context-menu'>
{/* <Draggable> */}
<Link
onClick={onClick}
to={link}
className={classNames(
`float-left scale-150 muted fill-current z-0`,
(channel.type === 'VOICE') ? 'mr-2' : 'mr-3',
)}
icon={icon} />
<ChannelTabContent />
<ChannelMenu channel={channel} />
</Link>
{/* </Draggable> */}
`cursor-pointer flex items-center rounded h-8 p-2 pl-3`,
{ active: channel.id === activeChannel?.id },
)}>
<FontAwesomeIcon
size="xs"
className={classNames(
`float-left scale-150 muted fill-current z-0`,
(channel.type === 'VOICE') ? 'mr-2' : 'mr-3',
)}
icon={icon} />
<ChannelTabContent />
<ChannelMenu channel={channel} />
</Link>
{/* </Draggable> */}
</div>
</ContextMenuTrigger>
<VCMembers />
</>

View File

@ -11,19 +11,21 @@ const SidebarIcons: React.FunctionComponent = () => {
const guildIcons = guilds.map(g => (
<ContextMenuTrigger key={g.id} id={g.id}>
<Link to={`/channels/${g.id}`}>
<SidebarIcon
to={`/channels/${g.id}`}
imageURL={g.iconURL}
name={g.name}
tooltip={g.name} />
</Link>
<GuildMenu guild={g} />
<div className="context-menu">
<Link to={`/channels/${g.id}`}>
<SidebarIcon
to={`/channels/${g.id}`}
imageURL={g.iconURL}
name={g.name}
tooltip={g.name} />
</Link>
<GuildMenu guild={g} />
</div>
</ContextMenuTrigger>
));
return (
<div className="overflow-auto min-h-screen float-left p-3 flex flex-col bg-bg-tertiary">
<div className="sidebar-icons overflow-auto min-h-screen float-left p-3 flex flex-col bg-bg-tertiary">
<Link to="/channels/@me">
<SidebarIcon
to="/channels/@me"

View File

@ -37,10 +37,10 @@ const MemberList: React.FunctionComponent = () => {
<ContextMenuTrigger
id={u.id}
key={u.id}>
<div className="m-2">
<div className="context-menu"> <div className="m-2">
<FoundUsername guild={guild} user={u} />
<GuildMemberMenu user={u} /></div>
</div>
<GuildMemberMenu user={u} />
</ContextMenuTrigger>
))}
</div>

View File

@ -12,7 +12,7 @@ const Dropdown: React.FunctionComponent<DropdownProps> = (props) => {
const dropdown = useSelector((s: Store.AppState) => s.ui.openDropdown);
return (
<div className="w-full pt-3">
<div className="dropdown bg-bg-tertiary w-full pt-3">
<div className="flex justify-between items-center">
<h1 className="flex-grow font-bold pl-2">{props.title}</h1>
<FontAwesomeIcon icon={faChevronDown} />

View File

@ -21,7 +21,7 @@
--bg-primary: transparent;
--bg-secondary: transparent;
--bg-secondary-alt: transparent;
--bg-tertiary: #050219;
--bg-tertiary: transparent;
--bg-textarea: #40444b;
--bg-modifier-accent: hsla(0, 0%, 100%, 0.06);
--bg-modifier-selected: rgba(79, 84, 92, 0.32);
@ -44,13 +44,44 @@ body {
.member-list {
background-image: url("https://newstarsgame.com/public/Purple/Layer%201/Space%20Background%201.png");
}
.sidebar-tabs {
background-image: url("https://newstarsgame.com/public/Purple/Layer%201/Space%20Background%2010.png");
background-image: url("https://newstarsgame.com/public/Purple/Layer%201/Space%20Background%2010.png");
}
.bg-bg-secondary {
/* background-image: url("https://newstarsgame.com/public/Purple/Layer%202/Space%20Background%202.png"); */
div.ReactModal__Content:not(.w-full),
.sidebar-icons *,
.context-menu,
input,
textarea,
label+* {
--warning: #f77d26;
--normal: #dcddde;
--link: hsl(197, calc(var(--saturation-factor, 1) * 100%), 47.8%);
--channel: #8e9297;
--saturation-factor: 1;
--bg-primary: #110E28;
--bg-secondary: #110E28;
--bg-secondary-alt: #110E28;
--bg-tertiary: #050219;
--bg-textarea: #40444b;
--bg-floating: #050219;
}
.bg-bg-tertiary {
.ReactModal__Overlay:hover {
animation: fade-in .2s ease-in-out;
}
div.ReactModal__Overlay {
background-image: url("https://newstarsgame.com/public/Purple/Layer%202/Space%20Background%2010.png") !important;
}
@keyframes fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}