Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Adding reverse share ability to copy the link #191

Merged
merged 14 commits into from
Jul 10, 2023
Merged
2 changes: 1 addition & 1 deletion backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"dev": "cross-env NODE_ENV=development nest start --watch",
"prod": "prisma migrate deploy && prisma db seed && node dist/src/main",
"lint": "eslint 'src/**/*.ts'",
"format": "prettier --write 'src/**/*.ts'",
"format": "prettier --end-of-line=auto --write 'src/**/*.ts'",
"test:system": "prisma migrate reset -f && nest start & wait-on http://localhost:8080/api/configs && newman run ./test/newman-system-tests.json"
},
"prisma": {
Expand Down
12 changes: 8 additions & 4 deletions backend/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
export const DATA_DIRECTORY = process.env.DATA_DIRECTORY || "./data";
export const SHARE_DIRECTORY = `${DATA_DIRECTORY}/uploads/shares`
export const DATABASE_URL = process.env.DATABASE_URL || "file:../data/pingvin-share.db?connection_limit=1";
export const CLAMAV_HOST = process.env.CLAMAV_HOST || (process.env.NODE_ENV == "docker" ? "clamav" : "127.0.0.1");
export const CLAMAV_PORT = parseInt(process.env.CLAMAV_PORT) || 3310;
export const SHARE_DIRECTORY = `${DATA_DIRECTORY}/uploads/shares`;
export const DATABASE_URL =
process.env.DATABASE_URL ||
"file:../data/pingvin-share.db?connection_limit=1";
export const CLAMAV_HOST =
process.env.CLAMAV_HOST ||
(process.env.NODE_ENV == "docker" ? "clamav" : "127.0.0.1");
export const CLAMAV_PORT = parseInt(process.env.CLAMAV_PORT) || 3310;
3 changes: 3 additions & 0 deletions backend/src/reverseShare/dto/reverseShare.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ export class ReverseShareDTO {
@Expose()
shareExpiration: Date;

@Expose()
token: string;

from(partial: Partial<ReverseShareDTO>) {
return plainToClass(ReverseShareDTO, partial, {
excludeExtraneousValues: true,
Expand Down
6 changes: 3 additions & 3 deletions backend/src/share/dto/myShare.dto.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Expose, plainToClass, Type } from "class-transformer";
import { ShareDTO } from "./share.dto";
import {FileDTO} from "../../file/dto/file.dto";
import {OmitType} from "@nestjs/swagger";
import { FileDTO } from "../../file/dto/file.dto";
import { OmitType } from "@nestjs/swagger";

export class MyShareDTO extends OmitType(ShareDTO, [
"files",
Expand Down Expand Up @@ -30,4 +30,4 @@ export class MyShareDTO extends OmitType(ShareDTO, [
plainToClass(MyShareDTO, part, { excludeExtraneousValues: true })
);
}
}
}
2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"build": "next build",
"start": "next start",
"lint": "next lint",
"format": "prettier --write \"src/**/*.ts*\""
"format": "prettier --end-of-line=auto --write \"src/**/*.ts*\""
},
"dependencies": {
"@emotion/react": "^11.10.6",
Expand Down
20 changes: 20 additions & 0 deletions frontend/src/components/account/showReverseShareLinkModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Stack, TextInput } from "@mantine/core";
import { ModalsContextProps } from "@mantine/modals/lib/context";

const showReverseShareLinkModal = (
modals: ModalsContextProps,
reverseShareToken: string,
appUrl: string
) => {
const link = `${appUrl}/upload/${reverseShareToken}`;
return modals.openModal({
title: "Reverse share link",
children: (
<Stack align="stretch">
<TextInput variant="filled" value={link} />
</Stack>
),
});
};

export default showReverseShareLinkModal;
8 changes: 4 additions & 4 deletions frontend/src/components/upload/CopyTextField.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useRef, useState } from "react";
import toast from "../../utils/toast.util";
import { ActionIcon, TextInput } from "@mantine/core";
import { TbCheck, TbCopy } from "react-icons/tb";
import { useClipboard } from "@mantine/hooks";
import { useRef, useState } from "react";
import { TbCheck, TbCopy } from "react-icons/tb";
import toast from "../../utils/toast.util";

function CopyTextField(props: { link: string }) {
const clipboard = useClipboard({ timeout: 500 });
Expand All @@ -14,7 +14,7 @@ function CopyTextField(props: { link: string }) {

const copyLink = () => {
clipboard.copy(props.link);
toast.success("Your link was copied to the keyboard.");
toast.success("The link was copied to your clipboard.");
if (timerRef.current) clearTimeout(timerRef.current);
timerRef.current = setTimeout(() => {
setCheckState(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ const CreateUploadModalBody = ({
}) => {
const modals = useModals();

const generatedLink = Buffer.from(Math.random().toString(), "utf8")
.toString("base64")
.substr(10, 7);

const [showNotSignedInAlert, setShowNotSignedInAlert] = useState(true);

const validationSchema = yup.object().shape({
Expand All @@ -78,7 +82,7 @@ const CreateUploadModalBody = ({
});
const form = useForm({
initialValues: {
link: "",
link: generatedLink,
recipients: [] as string[],
password: undefined,
maxViews: undefined,
Expand Down
46 changes: 39 additions & 7 deletions frontend/src/pages/account/reverseShares.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
Accordion,
ActionIcon,
Anchor,
Box,
Button,
Center,
Expand All @@ -16,9 +17,10 @@ import { useModals } from "@mantine/modals";
import moment from "moment";
import { useEffect, useState } from "react";
import { TbInfoCircle, TbLink, TbPlus, TbTrash } from "react-icons/tb";
import Meta from "../../components/Meta";
import showReverseShareLinkModal from "../../components/account/showReverseShareLinkModal";
import showShareLinkModal from "../../components/account/showShareLinkModal";
import CenterLoader from "../../components/core/CenterLoader";
import Meta from "../../components/Meta";
import showCreateReverseShareModal from "../../components/share/modals/showCreateReverseShareModal";
import useConfig from "../../hooks/config.hook";
import shareService from "../../services/share.service";
Expand All @@ -34,6 +36,8 @@ const MyShares = () => {

const [reverseShares, setReverseShares] = useState<MyReverseShare[]>();

const appUrl = config.get("general.appUrl");

const getReverseShares = () => {
shareService
.getMyReverseShares()
Expand Down Expand Up @@ -119,19 +123,22 @@ const MyShares = () => {
<Accordion.Panel>
{reverseShare.shares.map((share) => (
<Group key={share.id} mb={4}>
<Text maw={120} truncate>
{share.id}
</Text>
<Anchor
href={`${appUrl}/share/${share.id}`}
target="_blank"
>
<Text maw={120} truncate>
{share.id}
</Text>
</Anchor>
<ActionIcon
color="victoria"
variant="light"
size={25}
onClick={() => {
if (window.isSecureContext) {
clipboard.copy(
`${config.get(
"general.appUrl"
)}/share/${share.id}`
`${appUrl}/share/${share.id}`
);
toast.success(
"The share link was copied to the keyboard."
Expand Down Expand Up @@ -165,6 +172,31 @@ const MyShares = () => {
</td>
<td>
<Group position="right">
<ActionIcon
color="victoria"
variant="light"
size={25}
onClick={() => {
if (window.isSecureContext) {
clipboard.copy(
`${config.get("general.appUrl")}/upload/${
reverseShare.token
}`
);
toast.success(
"The link was copied to your clipboard."
);
} else {
showReverseShareLinkModal(
modals,
reverseShare.token,
config.get("general.appUrl")
);
}
}}
>
<TbLink />
</ActionIcon>
<ActionIcon
color="red"
variant="light"
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/pages/account/shares.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ import { useModals } from "@mantine/modals";
import moment from "moment";
import Link from "next/link";
import { useEffect, useState } from "react";
import { TbLink, TbTrash, TbInfoCircle } from "react-icons/tb";
import { TbInfoCircle, TbLink, TbTrash } from "react-icons/tb";
import Meta from "../../components/Meta";
import showShareInformationsModal from "../../components/account/showShareInformationsModal";
import showShareLinkModal from "../../components/account/showShareLinkModal";
import CenterLoader from "../../components/core/CenterLoader";
import Meta from "../../components/Meta";
import useConfig from "../../hooks/config.hook";
import shareService from "../../services/share.service";
import { MyShare } from "../../types/share.type";
import toast from "../../utils/toast.util";
import showShareInformationsModal from "../../components/account/showShareInformationsModal";

const MyShares = () => {
const modals = useModals();
Expand Down Expand Up @@ -122,7 +122,7 @@ const MyShares = () => {
}`
);
toast.success(
"Your link was copied to the keyboard."
"The link was copied to your clipboard."
);
} else {
showShareLinkModal(
Expand Down
1 change: 1 addition & 0 deletions frontend/src/types/share.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export type MyReverseShare = {
maxShareSize: string;
shareExpiration: Date;
remainingUses: number;
token: string;
shares: MyShare[];
};

Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,8 @@
"release:patch": "cd backend && npm version patch --commit-hooks false && cd ../frontend && npm version patch --commit-hooks false && cd .. && git add . && npm version patch --force -m 'release: %s' && git push && git push --tags",
"release:minor": "cd backend && npm version minor --commit-hooks false && cd ../frontend && npm version minor --commit-hooks false && cd .. && git add . && npm version minor --force -m 'release: %s' && git push && git push --tags",
"deploy:dev": "docker buildx build --push --tag stonith404/pingvin-share:development --platform linux/amd64,linux/arm64 ."
},
"devDependencies": {
"conventional-changelog-cli": "^3.0.0"
}
}