Add basic New Stars theme.
This commit is contained in:
parent
c11d516911
commit
01e0d7d454
@ -16,7 +16,7 @@ Built with React, TypeScript, and Node.js.
|
||||
## Setup
|
||||
|
||||
1. Clone the repo (from GitHub).
|
||||
2. Generate SSH keys (secure user logins).
|
||||
2. Generate JWT key (secure user logins).
|
||||
From app directory (with Git bash):
|
||||
```
|
||||
mkdir -p backend/keys
|
||||
|
@ -20,4 +20,10 @@ connect(process.env.MONGO_URI, {
|
||||
.then(async () => {
|
||||
log.info(`Connected to database.`, { uri: process.env.MONGO_URI });
|
||||
await User.updateMany({ $set: { status: 'OFFLINE' } })
|
||||
});
|
||||
});
|
||||
|
||||
try {
|
||||
process.env.SSH_KEY = fs.readFileSync('./keys/jwt', { encoding: 'utf-8' });
|
||||
log.info("JWT key initialized.");
|
||||
}
|
||||
catch { log.error("JWT key not setup correctly. Refer to the setup guide."); }
|
@ -68,11 +68,9 @@ export default class Users extends DBWrapper<string, UserDocument> {
|
||||
}
|
||||
|
||||
public async createToken(user: SelfUserDocument, expire = true) {
|
||||
// too insecure to keep in memory
|
||||
const key = await readFileAsync('./keys/jwt', { encoding: 'utf-8' });
|
||||
return jwt.sign(
|
||||
{ id: user.id },
|
||||
key,
|
||||
process.env.SSH_KEY,
|
||||
{ algorithm: 'RS512', expiresIn: (expire) ? '7d' : undefined },
|
||||
);
|
||||
}
|
||||
|
2
backend/types/dotenv.d.ts
vendored
2
backend/types/dotenv.d.ts
vendored
@ -9,6 +9,8 @@ declare global {
|
||||
ROOT_ENDPOINT: string;
|
||||
WEBSITE_URL: string;
|
||||
SESSION_SECRET: string;
|
||||
/** Set during runtime. */
|
||||
SSH_KEY: string;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
3
frontend/env/.env.dev
vendored
3
frontend/env/.env.dev
vendored
@ -5,4 +5,5 @@ REACT_APP_WEBSITE_URL="http://localhost:4200"
|
||||
REACT_APP_REPO_URL="https://github.com/theadamjr/acrd.app"
|
||||
REACT_APP_VERSION_NAME="Cyan"
|
||||
REACT_APP_VERSION_NUMBER="0.6.0-dev-release"
|
||||
REACT_APP_ROOT_API_URL="http://localhost:3000"
|
||||
REACT_APP_ROOT_API_URL="http://localhost:3000"
|
||||
REACT_APP_OWNER_USER_ID="450428712295456768"
|
3
frontend/env/.env.prod
vendored
3
frontend/env/.env.prod
vendored
@ -5,4 +5,5 @@ REACT_APP_WEBSITE_URL="https://acrd.app"
|
||||
REACT_APP_REPO_URL="https://github.com/theadamjr/acrd.app"
|
||||
REACT_APP_VERSION_NAME="Cyan"
|
||||
REACT_APP_VERSION_NUMBER="0.6.0-dev-release"
|
||||
REACT_APP_ROOT_API_URL="https://api.acrd.app"
|
||||
REACT_APP_ROOT_API_URL="https://api.acrd.app"
|
||||
REACT_APP_OWNER_USER_ID="451453819310678016"
|
@ -57,7 +57,7 @@ const TextBasedChannel: React.FunctionComponent = () => {
|
||||
<div
|
||||
id="messages"
|
||||
ref={messagesRef}
|
||||
className="overflow-auto mb-5 mr-1 mt-1 flex-grow"
|
||||
className="main-content bg-bg-primary overflow-auto mb-5 mr-1 mt-1 flex-grow"
|
||||
onScroll={onScroll}>
|
||||
<TextChannelHeader canRead={canRead} />
|
||||
<LoadingIndicator />
|
||||
|
@ -6,13 +6,15 @@ 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';
|
||||
import { updateSelf } from '../../../store/users';
|
||||
import { getUser, updateSelf } from '../../../store/users';
|
||||
import FileInput from '../../inputs/file-input';
|
||||
import Input from '../../inputs/input';
|
||||
import SidebarIcon from '../../navigation/sidebar/sidebar-icon';
|
||||
import CircleButton from '../../utils/buttons/circle-button';
|
||||
import NormalButton from '../../utils/buttons/normal-button';
|
||||
import SaveChanges from '../../utils/save-changes';
|
||||
import { Entity } from '@acrd/types';
|
||||
import FoundUsername from '../../user/username';
|
||||
|
||||
const UserSettingsThemes: React.FunctionComponent = () => {
|
||||
const dispatch = useDispatch();
|
||||
@ -57,6 +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));
|
||||
if (!theme) return null;
|
||||
|
||||
const onApply = () => dispatch(updateSelf({ activeThemeId: themeId }));
|
||||
@ -70,8 +73,8 @@ const UserSettingsThemes: React.FunctionComponent = () => {
|
||||
};
|
||||
|
||||
const copyCode = () => {
|
||||
const inviteURL = `${process.env.REACT_APP_WEBSITE_URL}/themes/${theme?.code}`;
|
||||
window.navigator.clipboard.writeText(inviteURL);
|
||||
const themeURL = `${process.env.REACT_APP_WEBSITE_URL}/themes/${theme?.code}`;
|
||||
window.navigator.clipboard.writeText(themeURL);
|
||||
}
|
||||
|
||||
const shortURL = process.env.REACT_APP_WEBSITE_URL
|
||||
@ -125,22 +128,29 @@ const UserSettingsThemes: React.FunctionComponent = () => {
|
||||
<header className="mb-5">
|
||||
<h1 className="text-3xl font-bold inline">{theme.name}</h1>
|
||||
</header>
|
||||
<div className="w-1/3">
|
||||
<FileInput
|
||||
disabled
|
||||
// disabled={true}!selfIsManager}
|
||||
name="icon"
|
||||
label="Icon"
|
||||
options={{ value: theme.iconURL }}
|
||||
tooltip="An optional icon for your theme."
|
||||
onChange={(e) => {
|
||||
const file = e.currentTarget?.files?.[0];
|
||||
if (!file) return;
|
||||
<div className="flex">
|
||||
<div className="w-1/3">
|
||||
<FileInput
|
||||
disabled={!selfIsManager}
|
||||
name="icon"
|
||||
label="Icon"
|
||||
options={{ value: theme.iconURL }}
|
||||
tooltip="An optional icon for your theme."
|
||||
onChange={(e) => {
|
||||
const file = e.currentTarget?.files?.[0];
|
||||
if (!file) return;
|
||||
|
||||
dispatch(uploadFile(file, ({ url }) => {
|
||||
dispatch(updateTheme(themeId, { iconURL: url }));
|
||||
}));
|
||||
}} />
|
||||
dispatch(uploadFile(file, ({ url }) => {
|
||||
dispatch(updateTheme(themeId, { iconURL: url }));
|
||||
}));
|
||||
}} />
|
||||
</div>
|
||||
<div style={{ margin: '20px' }}>
|
||||
<span className='text-center'>
|
||||
<div className="font-bold pb-1">Created By</div>
|
||||
<FoundUsername user={creatorUser} />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form
|
||||
@ -162,7 +172,7 @@ const UserSettingsThemes: React.FunctionComponent = () => {
|
||||
onClick={copyCode}
|
||||
className="float-right py-0">Copy</CircleButton>
|
||||
<span className="text-lg">
|
||||
<span className='muted'>{shortURL + '/join/'}</span>
|
||||
<span className='muted'>{shortURL + '/themes/'}</span>
|
||||
<span className='primary'>{theme?.code}</span>
|
||||
</span>
|
||||
</div>
|
||||
|
@ -11,7 +11,7 @@ const AppNavbar: React.FunctionComponent = () => {
|
||||
const memberListToggled = useSelector((s: Store.AppState) => s.config.memberListToggled);
|
||||
|
||||
return (
|
||||
<div className="shadow-elevation flex items-center h-12 px-5">
|
||||
<div className="bg-bg-primary shadow-elevation flex items-center h-12 px-5">
|
||||
{channel && <FontAwesomeIcon
|
||||
color="var(--muted)"
|
||||
icon={faHashtag}
|
||||
|
@ -4,9 +4,6 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { useEffect } from 'react';
|
||||
import { useDispatch, useSelector, useStore } from 'react-redux';
|
||||
import { Link, useHistory, useParams } from 'react-router-dom';
|
||||
import fetchEntities from '../../store/actions/fetch-entities';
|
||||
import { getGuild, getGuildMembers } from '../../store/guilds';
|
||||
import { joinGuild } from '../../store/members';
|
||||
import { applyTheme, getThemeByCode, getTheme, unlockTheme } from '../../store/themes';
|
||||
import { getUser, updateSelf } from '../../store/users';
|
||||
import SidebarIcon from '../navigation/sidebar/sidebar-icon';
|
||||
|
@ -56,7 +56,7 @@ const MemberList: React.FunctionComponent = () => {
|
||||
.map(r => r!.id);
|
||||
|
||||
return (isActive) ? (
|
||||
<div className="overflow-auto bg-bg-secondary w-64">
|
||||
<div className="member-list overflow-auto bg-bg-secondary w-64">
|
||||
{hoistedRoles.map(r =>
|
||||
<UserList
|
||||
key={r.id}
|
||||
|
@ -7,6 +7,7 @@ import { getHeaders } from './utils/rest-headers';
|
||||
import accordTheme from '!!raw-loader!../styles/theme/accord-theme.css';
|
||||
import discordTheme from '!!raw-loader!../styles/theme/discord-theme.css';
|
||||
import winterTheme from '!!raw-loader!../styles/theme/winter-theme.css';
|
||||
import newStarsTheme from '!!raw-loader!../styles/theme/new-stars-theme.css';
|
||||
import themeTemplate from '!!raw-loader!../styles/theme/winter-theme.css';
|
||||
|
||||
const slice = createSlice({
|
||||
@ -33,11 +34,20 @@ const slice = createSlice({
|
||||
id: 'winter',
|
||||
code: 'winter',
|
||||
createdAt: new Date('30/12/2021'),
|
||||
creatorId: '177127942839676928',
|
||||
creatorId: process.env.REACT_APP_OWNER_USER_ID,
|
||||
iconURL: '/images/themes/winter.svg',
|
||||
isFeatured: true,
|
||||
name: 'Winter (built-in)',
|
||||
styles: winterTheme,
|
||||
}, {
|
||||
id: 'new_stars',
|
||||
code: 'new_stars',
|
||||
createdAt: new Date('30/12/2021'),
|
||||
creatorId: process.env.REACT_APP_OWNER_USER_ID,
|
||||
iconURL: '/images/themes/.svg',
|
||||
isFeatured: true,
|
||||
name: 'New Stars (built-in)',
|
||||
styles: newStarsTheme,
|
||||
}] as Store.AppState['entities']['themes'],
|
||||
reducers: {
|
||||
deleted: (themes, { payload }: Store.Action<string>) => {
|
||||
|
56
frontend/src/styles/theme/new-stars-theme.css
Normal file
56
frontend/src/styles/theme/new-stars-theme.css
Normal file
@ -0,0 +1,56 @@
|
||||
/* newstarsgame.com */
|
||||
:root {
|
||||
--primary: yellow;
|
||||
--secondary: yellow;
|
||||
--tertiary: #30C0B8;
|
||||
|
||||
--heading: white;
|
||||
--font: #c9c9c9;
|
||||
--muted: #6c757d;
|
||||
|
||||
--success: #09f7a0;
|
||||
--danger: #f43e5c;
|
||||
--warning: #f77d26;
|
||||
|
||||
--normal: #dcddde;
|
||||
--link: hsl(197, calc(var(--saturation-factor, 1) * 100%), 47.8%);
|
||||
--channel: #8e9297;
|
||||
|
||||
--saturation-factor: 1;
|
||||
|
||||
--bg-primary: transparent;
|
||||
--bg-secondary: transparent;
|
||||
--bg-secondary-alt: transparent;
|
||||
--bg-tertiary: #050219;
|
||||
--bg-textarea: #40444b;
|
||||
--bg-modifier-accent: hsla(0, 0%, 100%, 0.06);
|
||||
--bg-modifier-selected: rgba(79, 84, 92, 0.32);
|
||||
--bg-floating: #18191c;
|
||||
|
||||
--elevation: 0 1px 0 rgba(4, 4, 5, 0.2), 0 1.5px 0 rgba(6, 6, 7, 0.05),
|
||||
0 2px 0 rgba(4, 4, 5, 0.05);
|
||||
|
||||
--font-primary: Inter, 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
|
||||
--light: #fdf0ed;
|
||||
--dark: #16161c;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
background-image: url("https://newstarsgame.com/public/Purple/Layer%203/Space%20Background%201.png") !important;
|
||||
}
|
||||
|
||||
.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");
|
||||
}
|
||||
|
||||
.bg-bg-secondary {
|
||||
/* background-image: url("https://newstarsgame.com/public/Purple/Layer%202/Space%20Background%202.png"); */
|
||||
}
|
||||
|
||||
.bg-bg-tertiary {
|
||||
}
|
1
frontend/types/dotenv.d.ts
vendored
1
frontend/types/dotenv.d.ts
vendored
@ -9,6 +9,7 @@ declare global {
|
||||
REACT_APP_VERSION_NAME: string;
|
||||
REACT_APP_VERSION_NUMBER: string;
|
||||
REACT_APP_ROOT_API_URL: string;
|
||||
REACT_APP_OWNER_USER_ID: string;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user