Skip to content

Commit

Permalink
update og image
Browse files Browse the repository at this point in the history
  • Loading branch information
thanhdanh27600 committed Aug 28, 2023
1 parent 5ce0471 commit e6438b3
Show file tree
Hide file tree
Showing 13 changed files with 101 additions and 39 deletions.
3 changes: 2 additions & 1 deletion public/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,6 @@
"advancedView": "Advanced info",
"loadMore": "Load more",
"editPreview": "More options",
"save": "Save"
"save": "Save",
"maximumCharaters": "Maximum of {{n}} characters"
}
3 changes: 2 additions & 1 deletion public/locales/vi/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,6 @@
"advancedView": "Xem nâng cao",
"loadMore": "Xem thêm",
"editPreview": "Chỉnh sửa",
"save": "Lưu thay đổi"
"save": "Lưu thay đổi",
"maximumCharaters": "Tối đa {{n}} ký tự"
}
8 changes: 7 additions & 1 deletion src/api/requests.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import memoize from 'fast-memoize';
import { stringify } from 'querystring';
import { Forward } from 'types/forward';
import { Locale } from 'types/locale';
import { QR } from 'types/qr';
import { ShortenUrl } from 'types/shorten';
import { Stats } from 'types/stats';
Expand All @@ -16,12 +17,15 @@ export const updateShortenUrlRequest = async ({
hash,
ogTitle,
ogDescription,
locale,
}: {
hash: string;
ogDescription?: string;
ogTitle?: string;
locale: Locale;
}) => {
const rs = await API.put(`/api/shorten/update`, {
locale,
hash,
ogTitle,
ogDescription,
Expand All @@ -32,16 +36,18 @@ export const updateShortenUrlRequest = async ({

export const getForwardUrl = async ({
hash,
locale,
userAgent,
ip,
fromClientSide,
}: {
hash: string;
locale: string;
userAgent?: string;
ip?: string | null;
fromClientSide?: boolean;
}) => {
const rs = await API.post(`/api/forward`, { hash, userAgent, ip, fromClientSide });
const rs = await API.post(`/api/forward`, { hash, locale, userAgent, ip, fromClientSide });
const data = rs.data;
return data as Forward;
};
Expand Down
45 changes: 33 additions & 12 deletions src/components/gadgets/AdvancedSettingUrlForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,26 @@ import { SubmitHandler, useForm } from 'react-hook-form';
import { toast } from 'react-hot-toast';
import { useMutation } from 'react-query';
import { LIMIT_OG_DESCRIPTION_LENGTH, LIMIT_OG_TITLE_LENGTH, brandUrlShortDomain } from 'types/constants';
import { Locale } from 'types/locale';
import { MIXPANEL_EVENT, MIXPANEL_STATUS } from 'types/utils';
import { debounce } from 'utils/data';
import { useTrans } from 'utils/i18next';
import { logger } from 'utils/logger';
import { QueryKey } from 'utils/requests';

type ShortenSettingPayload = Partial<UrlShortenerHistory> & { locale?: Locale };

export const AdvancedSettingUrlForm = () => {
const { t } = useTrans();
const { t, locale } = useTrans();
const { shortenSlice } = useBearStore();
const [shortenHistory, setShortenHistoryForm] = shortenSlice((state) => [
state.shortenHistory,
state.setShortenHistoryForm,
]);
const defaultValues = {
ogTitle: shortenHistory?.ogTitle ?? t('ogTitle', { hash: shortenHistory?.hash ?? 'XXX' }),
ogDescription: shortenHistory?.ogDescription ?? t('ogDescription'),
ogDomain: shortenHistory?.ogDomain ?? brandUrlShortDomain,
ogTitle: shortenHistory?.ogTitle || t('ogTitle', { hash: shortenHistory?.hash ?? 'XXX' }),
ogDescription: shortenHistory?.ogDescription || t('ogDescription'),
ogDomain: shortenHistory?.ogDomain || brandUrlShortDomain,
ogImgSrc: shortenHistory?.ogImgSrc,
};

Expand All @@ -35,11 +38,11 @@ export const AdvancedSettingUrlForm = () => {
handleSubmit,
formState: { errors },
watch,
} = useForm<Partial<UrlShortenerHistory>>({
} = useForm<ShortenSettingPayload>({
defaultValues,
});

const handleUpdate = useCallback((history: Partial<UrlShortenerHistory>) => {
const handleUpdate = useCallback((history: ShortenSettingPayload) => {
setShortenHistoryForm(history);
}, []);

Expand All @@ -49,11 +52,18 @@ export const AdvancedSettingUrlForm = () => {

useEffect(() => {
debouncedUpdate({
...shortenHistory,
ogTitle,
ogDescription,
});
}, [ogTitle, ogDescription, shortenHistory]);
}, [ogTitle, ogDescription]);

useEffect(() => {
if (shortenHistory)
debouncedUpdate({
ogTitle: shortenHistory.ogDescription || t('ogTitle', { hash: shortenHistory.hash ?? 'XXX' }),
ogDescription: shortenHistory.ogDescription || t('ogDescription'),
});
}, [shortenHistory]);

const updateShortenUrl = useMutation(QueryKey.SHORTEN_UPDATE, {
mutationFn: updateShortenUrlRequest,
Expand All @@ -72,10 +82,11 @@ export const AdvancedSettingUrlForm = () => {
},
});

const onSubmit: SubmitHandler<Partial<UrlShortenerHistory>> = async (values) => {
const onSubmit: SubmitHandler<ShortenSettingPayload> = async (values) => {
if (!shortenHistory?.hash) return;
updateShortenUrl.mutate({
hash: shortenHistory.hash,
locale,
ogDescription: values.ogDescription || undefined,
ogTitle: values.ogTitle || undefined,
});
Expand All @@ -92,26 +103,36 @@ export const AdvancedSettingUrlForm = () => {
btnSize="md"
{...register('ogTitle', {
required: { message: t('errorNoInput'), value: true },
maxLength: { message: `Maximum of ${LIMIT_OG_TITLE_LENGTH} charactors`, value: LIMIT_OG_TITLE_LENGTH },
maxLength: { message: t('maximumCharaters', { n: LIMIT_OG_TITLE_LENGTH }), value: LIMIT_OG_TITLE_LENGTH },
})}
maxLength={LIMIT_OG_TITLE_LENGTH}
disabled={updateShortenUrl.isLoading}
/>
<ErrorMessage
errors={errors}
name="ogTitle"
render={(error) => <p className="mt-4 text-red-400">{error.message}</p>}
render={(error) => <p className="text-red-400">{error.message}</p>}
/>
</div>
<div className="mt-4">
<label>Description</label>
<Textarea
{...register('ogDescription', {
required: { message: t('errorNoInput'), value: true },
maxLength: { message: `Maximum of ${LIMIT_OG_DESCRIPTION_LENGTH}}`, value: LIMIT_OG_DESCRIPTION_LENGTH },
maxLength: {
message: t('maximumCharaters', { n: LIMIT_OG_DESCRIPTION_LENGTH }),
value: LIMIT_OG_DESCRIPTION_LENGTH,
},
})}
maxLength={LIMIT_OG_DESCRIPTION_LENGTH}
rows={3}
disabled={updateShortenUrl.isLoading}
/>
<ErrorMessage
errors={errors}
name="ogDescription"
render={(error) => <p className="text-red-400">{error.message}</p>}
/>
</div>
<Button type="submit" text={t('save')} className="mt-4" loading={updateShortenUrl.isLoading} />
</div>
Expand Down
10 changes: 6 additions & 4 deletions src/components/gadgets/FacebookPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ import { useTrans } from 'utils/i18next';

export const FacebookPreview = ({ hash, ogTitle, ogDomain, ogDescription }: Partial<UrlShortenerHistory>) => {
const { t, locale } = useTrans();
const title = ogTitle ?? t('ogTitle', { hash: hash || 'XXX' });
const title = ogTitle || t('ogTitle', { hash: hash || 'XXX' });
let encodeTitle = '';
if (PLATFORM_AUTH) {
encodeTitle = encrypt(title);
}
return (
<div className="w-fit bg-gray-100/75 max-[420px]:overflow-scroll">
<div className="w-[420px]">
<div className="h-[221px] w-full border border-solid border-gray-200 bg-cover bg-no-repeat">
<div className="h-[220.5px] w-full border border-solid border-gray-200 bg-cover bg-no-repeat">
<iframe
className="relative origin-top-left scale-[0.35]"
width={1200}
Expand All @@ -29,9 +29,11 @@ export const FacebookPreview = ({ hash, ogTitle, ogDomain, ogDescription }: Part
{ogDomain ?? brandUrlShortDomain}
</span>
<div className="text-left">
<div className="font-facebook text-[16px] font-semibold text-[#1d2129]">{title}</div>
<div className="font-facebook text-[16px] font-semibold text-[#1d2129] line-clamp-2">{title}</div>
</div>
<span className="font-facebook text-sm text-[#606770]">{ogDescription ?? t('ogDescription')}</span>
<span className="mt-0.5 font-facebook text-sm text-[#606770] line-clamp-2">
{ogDescription ?? t('ogDescription')}
</span>
</div>
</div>
</div>
Expand Down
8 changes: 5 additions & 3 deletions src/components/gadgets/TwitterPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useTrans } from 'utils/i18next';

export const TwitterPreview = ({ hash, ogTitle, ogDomain, ogDescription }: Partial<UrlShortenerHistory>) => {
const { t, locale } = useTrans();
const title = ogTitle ?? t('ogTitle', { hash: hash || 'XXX' });
const title = ogTitle || t('ogTitle', { hash: hash || 'XXX' });
let encodeTitle = '';
if (PLATFORM_AUTH) {
encodeTitle = encrypt(title);
Expand All @@ -25,9 +25,11 @@ export const TwitterPreview = ({ hash, ogTitle, ogDomain, ogDescription }: Parti
</div>
<div className="rounded-xl rounded-t-none border border-t-0 border-solid border-gray-200 py-3 px-2.5">
<div className="text-left">
<div className="font-twitter font-bold text-[#18283e]">{title}</div>
<div className="font-twitter font-bold text-[#18283e] line-clamp-2">{title}</div>
</div>
<div className="mt-0.5 font-twitter text-sm text-[#18283e] line-clamp-2">
{ogDescription ?? t('ogDescription')}
</div>
<div className="mt-0.5 font-twitter text-sm text-[#18283e]">{ogDescription ?? t('ogDescription')}</div>
<div className="mt-0.5 border-separate text-ellipsis whitespace-nowrap break-words font-twitter text-sm lowercase text-[#8899a6]">
{ogDomain ?? brandUrlShortDomain}
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/components/sections/URLAdvancedSetting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useTrans } from 'utils/i18next';
import { URLSharePreview } from './URLSharePreview';

export const URLAdvancedSetting = () => {
const { t } = useTrans();
const { t, locale } = useTrans();

const title = (
<span className="relative">
Expand All @@ -20,7 +20,7 @@ export const URLAdvancedSetting = () => {
<Accordion title={title}>
<>
<URLSharePreview />
<AdvancedSettingUrlForm />
<AdvancedSettingUrlForm key={locale} />
<hr className="my-8" />
</>
</Accordion>
Expand Down
18 changes: 14 additions & 4 deletions src/controllers/forward.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import geoIp from 'geoip-country';
import { NextApiResponse } from 'next';
import { isEmpty } from 'ramda';
import prisma from '../db/prisma';
import { redis } from '../redis/client';
import { LIMIT_SHORTENED_SECOND, REDIS_KEY, getRedisKey } from '../types/constants';
Expand Down Expand Up @@ -27,11 +28,11 @@ export const handler = api(
}
const data = { hash, ip, userAgent, fromClientSide, lookupIp };
const hashShortenedLinkKey = getRedisKey(REDIS_KEY.HASH_SHORTEN_BY_HASH_URL, hash);
const shortenedUrlCache = await redis.hget(hashShortenedLinkKey, 'url');
if (shortenedUrlCache) {
const shortenedUrlCache = await redis.hgetall(hashShortenedLinkKey);
if (!isEmpty(shortenedUrlCache)) {
// cache hit
postProcessForward(data); // bypass process
return res.status(HttpStatusCode.OK).json({ history: { url: shortenedUrlCache } as any });
return res.status(HttpStatusCode.OK).json({ history: shortenedUrlCache as any });
}
// cache missed
await postProcessForward(data, res);
Expand Down Expand Up @@ -75,7 +76,16 @@ export const postProcessForward = async (payload: any, res?: NextApiResponse<For
if (res) {
// write back to cache
const hashShortenedLinkKey = getRedisKey(REDIS_KEY.HASH_SHORTEN_BY_HASH_URL, hash);
const dataHashShortenLink = ['url', history.url, 'updatedAt', new Date().getTime()];
const dataHashShortenLink = [
'url',
history.url,
'ogTitle',
history.ogTitle,
'ogDescription',
history.ogDescription,
'updatedAt',
new Date().getTime(),
];
await redis.hset(hashShortenedLinkKey, dataHashShortenLink);
await redis.expire(hashShortenedLinkKey, LIMIT_SHORTENED_SECOND);
return res.status(HttpStatusCode.OK).json({ history });
Expand Down
3 changes: 2 additions & 1 deletion src/controllers/og.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ const templateStylesOg = `
}
body {
padding: 3rem;
margin: 0;
width: 1200px;
height: 630px;
overflow: hidden;
Expand Down Expand Up @@ -93,7 +94,7 @@ main {
}
.title {
font-size: {{fontSize}};
margin: 0.25rem 0;
margin: 0.25rem;
font-weight: bold;
color: #fff;
text-shadow: .15em .15em 0 hsl(200 50% 30%);
Expand Down
10 changes: 9 additions & 1 deletion src/controllers/shorten/update.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { redis } from 'redis/client';
import { REDIS_KEY, getRedisKey } from 'types/constants';
import { Locale } from 'types/locale';
import prisma from '../../db/prisma';
import { ShortenUrl } from '../../types/shorten';
import { api, badRequest, successHandler } from '../../utils/axios';
Expand All @@ -6,10 +9,12 @@ import { validateUpdateShortenSchema } from '../../utils/validateMiddleware';
export const handler = api<ShortenUrl>(
async (req, res) => {
let hash = req.body.hash as string;
let locale = req.body.locale as string;
let ogTitle = req.body.ogTitle as string;
let ogDescription = req.body.ogDescription as string;
await validateUpdateShortenSchema.parseAsync({
hash,
locale,
ogTitle,
ogDescription,
});
Expand All @@ -22,7 +27,10 @@ export const handler = api<ShortenUrl>(
ogDescription,
},
});
successHandler(res, rs);
const ogKey = getRedisKey(REDIS_KEY.OG_BY_HASH, `${hash}-${locale || Locale.Vietnamese}`);
const hashShortenedLinkKey = getRedisKey(REDIS_KEY.HASH_SHORTEN_BY_HASH_URL, hash);
await Promise.all([redis.expire(ogKey, -1), redis.expire(hashShortenedLinkKey, -1)]);
return successHandler(res, rs);
},
['PUT'],
);
Loading

0 comments on commit e6438b3

Please sign in to comment.