Skip to content

Commit

Permalink
Redirect to linen if the thread exists
Browse files Browse the repository at this point in the history
  • Loading branch information
emilos committed Jun 27, 2023
1 parent 6067707 commit bf32a40
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 6 deletions.
20 changes: 20 additions & 0 deletions apps/web/bin/factory/communities/linen/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,26 @@ export default async function createLinenCommunity() {
},
},
});
// Thread with a link to the archive
await prisma.threads.create({
data: {
channelId: channel1.id,
sentAt: new Date().getTime(),
lastReplyAt: new Date('2021-12-09T08:41:00.000Z').getTime(),
externalThreadId: '1234567890.123456',
messages: {
create: [
{
channelId: channel1.id,
body: 'https://foo.slack.com/archives/C01AB34CDEF/p1234567890123456',
usersId: user3.id,
sentAt: '2021-12-09T08:41:00.000Z',
messageFormat: MessageFormat.LINEN,
},
],
},
},
});
// Thread with inline code blocks
await prisma.threads.create({
data: {
Expand Down
53 changes: 53 additions & 0 deletions apps/web/pages/api/link/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { NextApiRequest, NextApiResponse } from 'next/types';
import { prisma } from '@linen/database';

export async function create({ url }: { url: string }) {
if (isArchiveUrl(url)) {
const parts = url.split('/');
const last = parts[parts.length - 1];
if (last.startsWith('p')) {
const { length } = last;
const id =
last.slice(1, length - 6) + '.' + last.slice(length - 6, length);
const thread = await prisma.threads.findFirst({
where: {
externalThreadId: id,
},
});
if (thread) {
return {
status: 200,
data: {
incrementId: thread.incrementId,
},
};
} else {
return {
status: 404,
};
}
}
}
return {
status: 400,
};
}

function isArchiveUrl(input: string): boolean {
const url = new URL(input);
if (
url.hostname.endsWith('.slack.com') &&
url.pathname.startsWith('/archives/')
) {
return true;
}
return false;
}

export default async function handler(
request: NextApiRequest,
response: NextApiResponse
) {
const { status, data } = await create(request.body);
return response.status(status).json(data || {});
}
2 changes: 1 addition & 1 deletion packages/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -559,4 +559,4 @@
]
}
}
}
}
45 changes: 45 additions & 0 deletions packages/ui/src/GridRow/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
} from '@linen/types';
import styles from './index.module.scss';
import Actions from '@/Actions';
import { getThreadUrl } from '@linen/utilities/url';

function hasReaction(
message: SerializedMessage,
Expand All @@ -37,6 +38,16 @@ function hasReaction(
}
return !!reaction.users.find(({ id }) => id === userId);
}
function isArchiveUrl(input: string): boolean {
const url = new URL(input);
if (
url.hostname.endsWith('.slack.com') &&
url.pathname.startsWith('/archives/')
) {
return true;
}
return false;
}

interface Props {
className?: string;
Expand Down Expand Up @@ -151,6 +162,39 @@ function Row({
const top = !isPreviousMessageFromSameUser;
const resolution = thread.resolutionId === message.id;

function onLinkClick(event: React.MouseEvent<HTMLAnchorElement>) {
const url = event.currentTarget.href;
if (isArchiveUrl(url)) {
event.stopPropagation();
event.preventDefault();
fetch('/api/link', {
method: 'POST',
body: JSON.stringify({
url,
}),
headers: {
'Content-Type': 'application/json',
},
})
.then((response) => response.json())
.then(({ incrementId }) => {
if (incrementId) {
window.location.href = getThreadUrl({
isSubDomainRouting,
settings,
incrementId,
LINEN_URL:
process.env.NODE_ENV === 'development'
? 'http://localhost:3000'
: 'https://www.linen.dev',
});
} else {
window.location.href = url;
}
});
}
}

return (
<div
ref={ref}
Expand Down Expand Up @@ -208,6 +252,7 @@ function Row({
.filter(Boolean)}
attachments={message.attachments}
currentUser={currentUser}
onLinkClick={onLinkClick}
onLoad={onLoad}
placeholder={!inView}
/>
Expand Down
4 changes: 3 additions & 1 deletion packages/ui/src/Message/Link/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ import Mail from './Mail';
interface Props {
url: string;
title: string;
onClick?(event: React.MouseEvent<HTMLAnchorElement>): void;
onLoad?(): void;
}

export default function Link({ url, title, onLoad }: Props) {
export default function Link({ url, title, onClick, onLoad }: Props) {
if (isImage(url)) {
return (
<Accordion header={title}>
Expand Down Expand Up @@ -46,6 +47,7 @@ export default function Link({ url, title, onLoad }: Props) {
title={isHrefInvalid ? 'Invalid link' : ''}
rel="noreferrer ugc"
target={isExternalLink ? '_blank' : undefined}
onClick={onClick}
>
{title}
</a>
Expand Down
3 changes: 3 additions & 0 deletions packages/ui/src/Message/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ interface Props {
attachments?: SerializedAttachment[];
currentUser?: SerializedUser | null;
placeholder?: boolean;
onLinkClick?(event: React.MouseEvent<HTMLAnchorElement>): void;
onLoad?(): void;
}

Expand All @@ -66,6 +67,7 @@ function Message({
attachments,
currentUser,
placeholder,
onLinkClick,
onLoad,
}: Props) {
if (text === '' && noAttachment(attachments)) {
Expand Down Expand Up @@ -153,6 +155,7 @@ function Message({
key={node.cid}
url={(node as LinkNode).url}
title={(node as LinkNode).title}
onClick={onLinkClick}
onLoad={onLoad}
/>
);
Expand Down
2 changes: 1 addition & 1 deletion packages/utilities/src/url.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ describe('#getThreadUrl', () => {
it('returns the url of a thread', () => {
const url = getThreadUrl({
isSubDomainRouting: false,
settings: { communityName: 'linen', prefix: 's' },
settings: { communityName: 'linen' },
slug: 'test',
incrementId: 1,
LINEN_URL: 'https://www.linen.dev',
Expand Down
4 changes: 1 addition & 3 deletions packages/utilities/src/url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,21 +51,19 @@ export function getThreadUrl({
slug?: string | null;
incrementId: number;
settings: {
prefix?: string;
communityName?: string;
redirectDomain?: string;
};
messageId?: string;
LINEN_URL: string;
}) {
const slugLowerCase = (slug || 'topic').toLowerCase();
const prefix = settings?.prefix || 's';
const communityName = settings?.communityName;
const redirectDomain = settings?.redirectDomain;

const threadLink = isSubDomainRouting
? `https://${redirectDomain}/t/${incrementId}/${slugLowerCase}`
: `${LINEN_URL}/${prefix}/${communityName}/t/${incrementId}/${slugLowerCase}`;
: `${LINEN_URL}/s/${communityName}/t/${incrementId}/${slugLowerCase}`;

return `${threadLink}${!!messageId ? `#${messageId}` : ''}`;
}

1 comment on commit bf32a40

@vercel
Copy link

@vercel vercel bot commented on bf32a40 Jun 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.