fix: multiple issues & new features
This commit is contained in:
parent
4e64922b70
commit
e786482902
12 changed files with 231 additions and 1192 deletions
|
@ -10,11 +10,11 @@ COPY prisma ./prisma
|
||||||
|
|
||||||
COPY package.json yarn.lock next.config.js next-env.d.ts zip-env.d.ts tsconfig.json ./
|
COPY package.json yarn.lock next.config.js next-env.d.ts zip-env.d.ts tsconfig.json ./
|
||||||
|
|
||||||
RUN yarn install
|
|
||||||
|
|
||||||
# create a mock config.toml to spoof next build!
|
# create a mock config.toml to spoof next build!
|
||||||
RUN echo -e "[core]\nsecret = '12345678'\ndatabase_url = 'postgres://postgres:postgres@postgres/postgres'\n[uploader]\nroute = '/u'\ndirectory = './uploads'\n[urls]\nroute = '/go'" > config.toml
|
RUN echo -e "[core]\nsecret = '12345678'\ndatabase_url = 'postgres://postgres:postgres@postgres/postgres'\n[uploader]\nroute = '/u'\ndirectory = './uploads'\n[urls]\nroute = '/go'" > config.toml
|
||||||
|
|
||||||
|
RUN yarn install
|
||||||
|
|
||||||
RUN yarn build
|
RUN yarn build
|
||||||
|
|
||||||
FROM node:16-alpine3.11 AS runner
|
FROM node:16-alpine3.11 AS runner
|
||||||
|
|
|
@ -15,23 +15,15 @@ services:
|
||||||
retries: 5
|
retries: 5
|
||||||
|
|
||||||
zipline:
|
zipline:
|
||||||
image: ghcr.io/diced/zipline/zipline:trunk
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
ports:
|
ports:
|
||||||
- '3000:3000'
|
- '3000:3000'
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
- SECURE=false
|
|
||||||
- SECRET=changethis
|
- SECRET=changethis
|
||||||
- HOST=0.0.0.0
|
|
||||||
- PORT=3000
|
|
||||||
- DATABASE_URL=postgresql://postgres:postgres@postgres/postgres/
|
- DATABASE_URL=postgresql://postgres:postgres@postgres/postgres/
|
||||||
- UPLOADER_ROUTE=/u
|
|
||||||
- UPLOADER_EMBED_ROUTE=/a
|
|
||||||
- UPLOADER_LENGTH=6
|
|
||||||
- UPLOADER_DIRECTORY=./uploads
|
|
||||||
- UPLOADER_ADMIN_LIMIT=104900000
|
|
||||||
- UPLOADER_USER_LIMIT=104900000
|
|
||||||
- UPLOADER_DISABLED_EXTS=
|
|
||||||
volumes:
|
volumes:
|
||||||
- '$PWD/uploads:/zipline/uploads'
|
- '$PWD/uploads:/zipline/uploads'
|
||||||
- '$PWD/public:/zipline/public'
|
- '$PWD/public:/zipline/public'
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "zip3",
|
"name": "zip3",
|
||||||
"version": "3.3.0",
|
"version": "3.3.1",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prepare": "husky install",
|
"prepare": "husky install",
|
||||||
"dev": "NODE_ENV=development node server",
|
"dev": "NODE_ENV=development node server",
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
"@mui/icons-material": "^5.0.0",
|
"@mui/icons-material": "^5.0.0",
|
||||||
"@mui/material": "^5.0.2",
|
"@mui/material": "^5.0.2",
|
||||||
"@mui/styles": "^5.0.1",
|
"@mui/styles": "^5.0.1",
|
||||||
"@prisma/client": "^3.7.0",
|
"@prisma/client": "^3.9.2",
|
||||||
"@reduxjs/toolkit": "^1.6.0",
|
"@reduxjs/toolkit": "^1.6.0",
|
||||||
"argon2": "^0.28.2",
|
"argon2": "^0.28.2",
|
||||||
"colorette": "^1.2.2",
|
"colorette": "^1.2.2",
|
||||||
|
@ -27,8 +27,8 @@
|
||||||
"fecha": "^4.2.1",
|
"fecha": "^4.2.1",
|
||||||
"formik": "^2.2.9",
|
"formik": "^2.2.9",
|
||||||
"multer": "^1.4.2",
|
"multer": "^1.4.2",
|
||||||
"next": "^12.0.7",
|
"next": "^12.0.10",
|
||||||
"prisma": "^3.7.0",
|
"prisma": "^3.9.2",
|
||||||
"react": "17.0.2",
|
"react": "17.0.2",
|
||||||
"react-color": "^2.19.3",
|
"react-color": "^2.19.3",
|
||||||
"react-dom": "17.0.2",
|
"react-dom": "17.0.2",
|
||||||
|
|
|
@ -13,15 +13,16 @@ const validator = yup.object({
|
||||||
stats_interval: yup.number().default(1800),
|
stats_interval: yup.number().default(1800),
|
||||||
}).required(),
|
}).required(),
|
||||||
uploader: yup.object({
|
uploader: yup.object({
|
||||||
route: yup.string().required(),
|
route: yup.string().default('/u'),
|
||||||
|
embed_route: yup.string().default('/a'),
|
||||||
length: yup.number().default(6),
|
length: yup.number().default(6),
|
||||||
directory: yup.string().required(),
|
directory: yup.string().default('./uploads'),
|
||||||
admin_limit: yup.number().default(104900000),
|
admin_limit: yup.number().default(104900000),
|
||||||
user_limit: yup.number().default(104900000),
|
user_limit: yup.number().default(104900000),
|
||||||
disabled_extensions: yup.array().default([]),
|
disabled_extensions: yup.array().default([]),
|
||||||
}).required(),
|
}).required(),
|
||||||
urls: yup.object({
|
urls: yup.object({
|
||||||
route: yup.string().required(),
|
route: yup.string().default('/go'),
|
||||||
length: yup.number().default(6),
|
length: yup.number().default(6),
|
||||||
}).required(),
|
}).required(),
|
||||||
ratelimit: yup.object({
|
ratelimit: yup.object({
|
||||||
|
|
|
@ -11,6 +11,8 @@ import ayu_light from 'lib/themes/ayu_light';
|
||||||
import nord from 'lib/themes/nord';
|
import nord from 'lib/themes/nord';
|
||||||
import polar from 'lib/themes/polar';
|
import polar from 'lib/themes/polar';
|
||||||
import dracula from 'lib/themes/dracula';
|
import dracula from 'lib/themes/dracula';
|
||||||
|
import matcha_dark_azul from 'lib/themes/matcha_dark_azul';
|
||||||
|
import qogir_dark from 'lib/themes/qogir_dark';
|
||||||
|
|
||||||
import { useStoreSelector } from 'lib/redux/store';
|
import { useStoreSelector } from 'lib/redux/store';
|
||||||
import createTheme from 'lib/themes';
|
import createTheme from 'lib/themes';
|
||||||
|
@ -24,6 +26,8 @@ export const themes = {
|
||||||
'nord': nord,
|
'nord': nord,
|
||||||
'polar': polar,
|
'polar': polar,
|
||||||
'dracula': dracula,
|
'dracula': dracula,
|
||||||
|
'matcha_dark_azul': matcha_dark_azul,
|
||||||
|
'qogir_dark': qogir_dark,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const friendlyThemeName = {
|
export const friendlyThemeName = {
|
||||||
|
@ -35,6 +39,8 @@ export const friendlyThemeName = {
|
||||||
'nord': 'Nord',
|
'nord': 'Nord',
|
||||||
'polar': 'Polar',
|
'polar': 'Polar',
|
||||||
'dracula': 'Dracula',
|
'dracula': 'Dracula',
|
||||||
|
'matcha_dark_azul': 'Matcha Dark Azul',
|
||||||
|
'qogir_dark': 'Qogir Dark',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function ZiplineTheming({ Component, pageProps }) {
|
export default function ZiplineTheming({ Component, pageProps }) {
|
||||||
|
|
|
@ -17,9 +17,14 @@ import {
|
||||||
Card as MuiCard,
|
Card as MuiCard,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import AudioIcon from '@mui/icons-material/Audiotrack';
|
import AudioIcon from '@mui/icons-material/Audiotrack';
|
||||||
|
import DeleteIcon from '@mui/icons-material/Delete';
|
||||||
|
import CopyIcon from '@mui/icons-material/FileCopy';
|
||||||
|
import OpenIcon from '@mui/icons-material/OpenInNew';
|
||||||
|
|
||||||
import Link from 'components/Link';
|
import Link from 'components/Link';
|
||||||
import Card from 'components/Card';
|
import Card from 'components/Card';
|
||||||
|
import Alert from 'components/Alert';
|
||||||
|
import copy from 'copy-to-clipboard';
|
||||||
import useFetch from 'lib/hooks/useFetch';
|
import useFetch from 'lib/hooks/useFetch';
|
||||||
import { useStoreSelector } from 'lib/redux/store';
|
import { useStoreSelector } from 'lib/redux/store';
|
||||||
|
|
||||||
|
@ -95,6 +100,10 @@ export default function Dashboard() {
|
||||||
const [stats, setStats] = useState(null);
|
const [stats, setStats] = useState(null);
|
||||||
const [rowsPerPage, setRowsPerPage] = useState(10);
|
const [rowsPerPage, setRowsPerPage] = useState(10);
|
||||||
|
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const [severity, setSeverity] = useState('success');
|
||||||
|
const [message, setMessage] = useState('Saved');
|
||||||
|
|
||||||
const updateImages = async () => {
|
const updateImages = async () => {
|
||||||
const imgs = await useFetch('/api/user/files');
|
const imgs = await useFetch('/api/user/files');
|
||||||
const recent = await useFetch('/api/user/recent?filter=media');
|
const recent = await useFetch('/api/user/recent?filter=media');
|
||||||
|
@ -124,6 +133,8 @@ export default function Dashboard() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<Alert open={open} setOpen={setOpen} message={message} severity={severity} />
|
||||||
|
|
||||||
<Typography variant='h4'>Welcome back {user?.username}</Typography>
|
<Typography variant='h4'>Welcome back {user?.username}</Typography>
|
||||||
<Typography color='GrayText' pb={2}>You have <b>{images.length ? images.length : '...'}</b> files</Typography>
|
<Typography color='GrayText' pb={2}>You have <b>{images.length ? images.length : '...'}</b> files</Typography>
|
||||||
|
|
||||||
|
@ -162,7 +173,7 @@ export default function Dashboard() {
|
||||||
<Card name='Images' sx={{ height: '100%' }}>
|
<Card name='Images' sx={{ height: '100%' }}>
|
||||||
<StatText>{stats ? stats.count : <Skeleton variant='text' />}</StatText>
|
<StatText>{stats ? stats.count : <Skeleton variant='text' />}</StatText>
|
||||||
<Typography variant='h3'>Views</Typography>
|
<Typography variant='h3'>Views</Typography>
|
||||||
<StatText>{stats ? `${stats.views_count} (${isNaN(stats.views_count / stats.count) ? '0' : stats.views_count / stats.count})` : <Skeleton variant='text' />}</StatText>
|
<StatText>{stats ? `${stats.views_count} (${isNaN(stats.views_count / stats.count) ? 0 : Math.round(stats.views_count / stats.count)})` : <Skeleton variant='text' />}</StatText>
|
||||||
</Card>
|
</Card>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12} sm={4}>
|
<Grid item xs={12} sm={4}>
|
||||||
|
@ -206,8 +217,15 @@ export default function Dashboard() {
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
<TableCell align='right' sx={{ borderColor: t => t.palette.divider }}>
|
<TableCell align='right' sx={{ borderColor: t => t.palette.divider }}>
|
||||||
<ButtonGroup variant='outlined'>
|
<ButtonGroup variant='text'>
|
||||||
<Button onClick={() => handleDelete(row)} color='error' size='small'>Delete</Button>
|
<Button onClick={() => handleDelete(row)} color='error' size='small'><DeleteIcon /></Button>
|
||||||
|
<Button onClick={() => window.open(row.url, '_blank')} color='warning' size='small'><OpenIcon /></Button>
|
||||||
|
<Button onClick={() => {
|
||||||
|
copy(window.location.origin + row.url);
|
||||||
|
setOpen(true);
|
||||||
|
setSeverity('success');
|
||||||
|
setMessage('Copied to clipboard');
|
||||||
|
}} color='info' size='small'><CopyIcon /></Button>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
|
|
|
@ -67,7 +67,7 @@ function VarsTooltip({ children }) {
|
||||||
<Typography><b>{'{image.mimetype}'}</b> - mimetype</Typography>
|
<Typography><b>{'{image.mimetype}'}</b> - mimetype</Typography>
|
||||||
<Typography><b>{'{image.id}'}</b> - id of the image</Typography>
|
<Typography><b>{'{image.id}'}</b> - id of the image</Typography>
|
||||||
<Typography><b>{'{user.name}'}</b> - your username</Typography>
|
<Typography><b>{'{user.name}'}</b> - your username</Typography>
|
||||||
visit <Link href='https://zipline.diced.me/docs/variables'>the docs</Link> for more variables
|
visit <Link href='https://zipline.diced.cf/docs/variables'>the docs</Link> for more variables
|
||||||
</>
|
</>
|
||||||
}>
|
}>
|
||||||
{children}
|
{children}
|
||||||
|
@ -97,7 +97,7 @@ export default function Manage() {
|
||||||
...(withEmbed && {Embed: 'true'}),
|
...(withEmbed && {Embed: 'true'}),
|
||||||
...(withZws && {ZWS: 'true'}),
|
...(withZws && {ZWS: 'true'}),
|
||||||
},
|
},
|
||||||
URL: '$json:url$',
|
URL: '$json:files[0]$',
|
||||||
Body: 'MultipartFormData',
|
Body: 'MultipartFormData',
|
||||||
FileFormName: 'file',
|
FileFormName: 'file',
|
||||||
};
|
};
|
||||||
|
@ -196,7 +196,7 @@ export default function Manage() {
|
||||||
|
|
||||||
<Typography variant='h4'>Manage User</Typography>
|
<Typography variant='h4'>Manage User</Typography>
|
||||||
<VarsTooltip>
|
<VarsTooltip>
|
||||||
<Typography variant='caption' color='GrayText'>Want to use variables in embed text? Hover on this or visit <Link href='https://zipline.diced.me/docs/variables'>the docs</Link> for more variables</Typography>
|
<Typography variant='caption' color='GrayText'>Want to use variables in embed text? Hover on this or visit <Link href='https://zipline.diced.cf/docs/variables'>the docs</Link> for more variables</Typography>
|
||||||
</VarsTooltip>
|
</VarsTooltip>
|
||||||
<form onSubmit={formik.handleSubmit}>
|
<form onSubmit={formik.handleSubmit}>
|
||||||
<TextInput fullWidth id='username' label='Username' formik={formik} />
|
<TextInput fullWidth id='username' label='Username' formik={formik} />
|
||||||
|
|
|
@ -32,6 +32,8 @@ module.exports = () => {
|
||||||
Logger.get('config').info('reading environment');
|
Logger.get('config').info('reading environment');
|
||||||
return tryReadEnv();
|
return tryReadEnv();
|
||||||
} else {
|
} else {
|
||||||
|
if (process.env.JEST_WORKER_ID) return;
|
||||||
|
|
||||||
Logger.get('config').info('reading config file');
|
Logger.get('config').info('reading config file');
|
||||||
const str = readFileSync(join(process.cwd(), 'config.toml'), 'utf8');
|
const str = readFileSync(join(process.cwd(), 'config.toml'), 'utf8');
|
||||||
const parsed = require('@iarna/toml/parse-string')(str);
|
const parsed = require('@iarna/toml/parse-string')(str);
|
||||||
|
|
15
src/lib/themes/matcha_dark_azul.ts
Normal file
15
src/lib/themes/matcha_dark_azul.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import createTheme from '.';
|
||||||
|
|
||||||
|
export default createTheme({
|
||||||
|
type: 'dark',
|
||||||
|
primary: '#3498db',
|
||||||
|
secondary: '#7344e2',
|
||||||
|
error: '#db5b5b',
|
||||||
|
warning: '#ff9800',
|
||||||
|
info: '#2f6fb9',
|
||||||
|
border: '#14161b',
|
||||||
|
background: {
|
||||||
|
main: '#1b1d24',
|
||||||
|
paper: '#202329',
|
||||||
|
},
|
||||||
|
});
|
15
src/lib/themes/qogir_dark.ts
Normal file
15
src/lib/themes/qogir_dark.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import createTheme from '.';
|
||||||
|
|
||||||
|
export default createTheme({
|
||||||
|
type: 'dark',
|
||||||
|
primary: '#5294e2',
|
||||||
|
secondary: '#7344e2',
|
||||||
|
error: '##f04a50',
|
||||||
|
warning: '#ff9800',
|
||||||
|
info: '#2f6fb9',
|
||||||
|
border: '#4a4c54',
|
||||||
|
background: {
|
||||||
|
main: '#32343d',
|
||||||
|
paper: '#262830',
|
||||||
|
},
|
||||||
|
});
|
|
@ -23,7 +23,6 @@ export default function EmbeddedImage({ image, user, normal }) {
|
||||||
else imageEl.width = original.width;
|
else imageEl.width = original.width;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (typeof window !== 'undefined') window.onresize = () => updateImage();
|
|
||||||
useEffect(() => updateImage(), []);
|
useEffect(() => updateImage(), []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
Loading…
Reference in a new issue