Skip to content

Commit

Permalink
Merge pull request #96 from wwsalmon/redirects
Browse files Browse the repository at this point in the history
Redirects
  • Loading branch information
wwsalmon authored Aug 18, 2023
2 parents 24bc18a + 2d80b4d commit 5568be2
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 65 deletions.
4 changes: 2 additions & 2 deletions components/Activity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,14 @@ const Activity = ({ updates, pageUser, onClickDate }: { updates: { date: string
</span>
<button
onClick={() => setYear("last-year")}
className={classNames("pb-0.5 border-b-2 whitespace-nowrap", ("last-year" === year) ? "border-stone-700 text-stone-700 font-bold" : "text-stone-400 border-transparent")}
className={classNames("pb-0.5 border-b-2 whitespace-nowrap", ("last-year" === year) ? "border-neutral-700 text-neutral-700 dark:text-white dark:border-white font-bold" : "text-neutral-400 dark:text-neutral-500 border-transparent")}
>Last year</button>
{/* get the years that the user has written updates and display them as tabs above */}
{years.map(y => (
<button
key={y}
onClick={() => setYear(y)}
className={classNames("pb-0.5 border-b-2", (y === year) ? "border-stone-700 text-stone-700 font-bold" : "text-stone-400 border-transparent")}
className={classNames("pb-0.5 border-b-2", (y === year) ? "border-neutral-700 text-neutral-700 dark:text-white dark:border-white font-bold" : "text-neutral-400 dark:text-neutral-500 border-transparent")}
>{y}</button>
))}
</div >
Expand Down
6 changes: 3 additions & 3 deletions components/ActivityGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ const GridLabel = ({ row, col, children }: { row: number, col: number, children:
gridColumn: col,
fontSize: 10,
}}
className="text-stone-300 dark:text-stone-700"
className="text-neutral-300 dark:text-neutral-700"
><span>{children}</span></div>
)

export default function ActivityGrid({ data, label, color, onClickDate }: { data: ActivityDayMap, label?: string, color?: string, onClickDate: (date: string) => void }) {
export default function ActivityGrid({ data, onClickDate }: { data: ActivityDayMap, onClickDate: (date: string) => void }) {
const numCols = 53;

const monthChangeDays: ActivityDay[] = Object.values(data).filter((d, i, a) => (
Expand Down Expand Up @@ -58,7 +58,7 @@ export default function ActivityGrid({ data, label, color, onClickDate }: { data
gridRow: dateActivity.day + 2,
gridColumn: dateActivity.week + 2,
}}
className={classNames(dateActivity.count > 0 ? "bg-tblue cursor-pointer" : "bg-gray-100", "hover:!opacity-100 w-[13px] h-[13px] rounded-[3px]")}
className={classNames(dateActivity.count > 0 ? "bg-tblue cursor-pointer" : "bg-gray-100 dark:bg-neutral-800", "hover:!opacity-100 w-[13px] h-[13px] rounded-[3px]")}
key={format(dateActivity.date, "yyyy-MM-dd")}
onClick={() => {
if (dateActivity.count > 0)
Expand Down
104 changes: 53 additions & 51 deletions components/CustomSelect.tsx
Original file line number Diff line number Diff line change
@@ -1,60 +1,62 @@
import { useTheme } from 'next-themes';
import Select from 'react-select'

export default function CustomSelect(props) {
const { theme, setTheme } = useTheme();
const customStyles = {
option: (provided, state) => {
const optionBackgroundColor = state.isSelected
? 'rgb(38, 132, 255)' /* default */
: theme === 'dark'
? '#000'
: '#FFF';

return {
...provided,
padding: 8,
paddingRight: 16,
paddingLeft: 16,
backgroundColor: optionBackgroundColor,

':hover': {
backgroundColor: state.isSelected
? optionBackgroundColor
: theme === 'dark'
? 'rgba(243, 244, 246, 0.2)'
: 'rgba(243, 244, 246, 1)', // tailwind gray 100, just like moremenu on hover
},
};
},

valueContainer: provided => ({
export const getCustomStyles = (theme) => ({
option: (provided, state) => {
const optionBackgroundColor = state.isSelected
? 'rgb(38, 132, 255)' /* default */
: theme === 'dark'
? '#000'
: '#FFF';

return {
...provided,
padding: 8,
paddingRight: 16,
paddingLeft: 16,
}),

control: provided => ({
...provided,
borderColor: '#e5e7eb',
backgroundColor: theme === 'dark' ? 'rgba(0, 0, 0, 0)' : '#FFF',
}),

container: provided => ({
...provided,
marginBottom: 8,
}),
backgroundColor: optionBackgroundColor,

':hover': {
backgroundColor: state.isSelected
? optionBackgroundColor
: theme === 'dark'
? 'rgba(243, 244, 246, 0.2)'
: 'rgba(243, 244, 246, 1)', // tailwind gray 100, just like moremenu on hover
},
};
},

valueContainer: provided => ({
...provided,
padding: 8,
paddingRight: 16,
paddingLeft: 16,
}),

control: provided => ({
...provided,
borderColor: '#e5e7eb',
backgroundColor: theme === 'dark' ? 'rgba(0, 0, 0, 0)' : '#FFF',
}),

container: provided => ({
...provided,
marginBottom: 8,
}),

menu: provided => ({
...provided,
backgroundColor: theme === 'dark' ? '#000' : '#FFF',
}),

singleValue: provided => ({
...provided,
color: theme === 'dark' ? '#FFF' : '#000',
}),
});

menu: provided => ({
...provided,
backgroundColor: theme === 'dark' ? '#000' : '#FFF',
}),

singleValue: provided => ({
...provided,
color: theme === 'dark' ? '#FFF' : '#000',
}),
};
return <Select {...props} customStyles={customStyles} />
export default function CustomSelect(props) {
const { theme, setTheme } = useTheme();
const customStyles = getCustomStyles(theme);
return <Select {...props} customStyles={customStyles} />
}
8 changes: 6 additions & 2 deletions components/EditUpdate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {User} from "../utils/types";
import axios from "axios";
import MentionItem from "./MentionItem";
import Creatable from "react-select/creatable";
import { getCustomStyles } from "./CustomSelect";
import { useTheme } from "next-themes";

function getMentionFromCM(instance) {
const cursorInfo = instance.getCursor();
Expand Down Expand Up @@ -110,6 +112,8 @@ export default function EditUpdate({body, setBody, title, setTitle, date, setDat

return () => editorEl.removeEventListener("keydown", keydownHandler);
}, [editorRef.current, mentionOpen, mentionQuery, userSelectedIndex, userList]);

const { theme, setTheme } = useTheme();

return (
<>
Expand Down Expand Up @@ -141,8 +145,8 @@ export default function EditUpdate({body, setBody, title, setTitle, date, setDat

<div className="my-8 md:my-0 md:w-1/2">
<div className="up-ui-title mt-4 mb-5"><span>Tags (optional)</span></div>
<Creatable options={userTags.map(d => ({ value: d, label: d }))} isMulti={true} isClearable={true}
onChange={option => setTags(option.map(d => d.value))} defaultValue={tags.map(d => ({value: d, label: d}))} />
<Creatable options={userTags.map(d => ({ value: d, label: d }))} isMulti={true} isClearable={true} className="z-10 relative"
onChange={option => setTags(option.map(d => d.value))} defaultValue={tags.map(d => ({value: d, label: d}))} styles={{...getCustomStyles(theme), multiValueRemove: (styles) => ({...styles, color: "black"})}}/>
</div>

</div>
Expand Down
2 changes: 1 addition & 1 deletion components/UpdateFeed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export default function UpdateFeed({updates, page, setPage, count}: {updates: Fe
<span className="opacity-50">{wordsCount(update.body)} word{wordsCount(update.body) > 1 ? "s" : ""}</span>
</p>
{update.tags && update.tags.map(tag => (
<div key={tag} className="px-2 py-1 bg-gray-700 hover:bg-gray-900 transition font-medium border rounded text-xs text-white mr-2">#{tag}</div>
<div key={tag} className="px-2 py-1 bg-neutral-700 hover:bg-neutral-900 transition font-medium border rounded text-xs text-white mr-2">#{tag}</div>
))}
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "updately",
"version": "0.11.2",
"version": "0.11.3",
"private": true,
"license": "BSD-3-Clause",
"scripts": {
Expand Down
5 changes: 3 additions & 2 deletions pages/[username]/[updateUrl].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {FiHeart} from "react-icons/fi";
import {notificationModel} from "../../models/models";
import {getMentionsAndBodySegments} from "../../components/UpdateCommentItem";
import { DeleteModal } from "../../components/Modal";
import { ssrRedirect } from "next-response-helpers";

export default function UpdatePage(props: { data: GetUpdateRequestResponse, updateUrl: string, userData: User }) {
const router = useRouter();
Expand Down Expand Up @@ -171,7 +172,7 @@ export default function UpdatePage(props: { data: GetUpdateRequestResponse, upda
{!!tags.length && (
<div className="flex items-center my-8">
{tags.map(d => (
<a href={`/@${data.user.urlName}?tag=${encodeURIComponent(d)}`} key={d} className="px-2 py-1 bg-gray-700 hover:bg-gray-900 transition font-medium border rounded text-sm text-white mr-2">#{d}</a>
<a href={`/@${data.user.urlName}?tag=${encodeURIComponent(d)}`} key={d} className="px-2 py-1 bg-neutral-700 hover:bg-neutral-900 transition font-medium border rounded text-sm text-white mr-2">#{d}</a>
))}
</div>
)}
Expand Down Expand Up @@ -288,7 +289,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => {
// or are the user
data.user._id.toString() === userData._id.toString()
)
)) return { notFound: true };
)) return ssrRedirect(`/@${data.user.urlName}?privateredirect=true`);

if (userData) await notificationModel.updateMany({userId: userData._id, updateId: data.update._id}, {read: true});

Expand Down
9 changes: 8 additions & 1 deletion pages/[username]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,19 @@ export default function UserProfile(props: { user: UserAgg, userData: User, foll

const isProfilePrivateToLoggedInUser = (pageUser.private || pageUser.truePrivate) && (!userData || !pageUser.followers.includes(props.userData.email) && !isOwner);

const isPrivateUpdateRedirect = !!router.query.privateredirect;

return (
<div className="max-w-4xl mx-auto px-4">
<NextSeo
title={`${pageUser.name}'s daily updates | Updately`}
description={`Follow ${pageUser.name} on Updately to get their updates in your feed.`}
/>
{isPrivateUpdateRedirect && (
<div className="my-16 bg-black p-4 text-white rounded">
<p>You accessed a link to an update on a private account that you do not follow. Follow the account to view the update.</p>
</div>
)}
<div className="sm:flex mt-16 mb-8">
<UserHeaderLeft pageUser={pageUser} userData={userData}/>
<div className="flex sm:ml-auto mt-6 sm:mt-0">
Expand Down Expand Up @@ -245,7 +252,7 @@ export default function UserProfile(props: { user: UserAgg, userData: User, foll
</a>
</p>
{update.tags && update.tags.map(tag => (
<button onClick={() => setFilterBy(tag)} key={tag} className="px-2 py-1 bg-gray-700 hover:bg-gray-900 transition font-medium border rounded text-xs text-white mr-2">#{tag}</button>
<button onClick={() => setFilterBy(tag)} key={tag} className="px-2 py-1 bg-neutral-700 hover:bg-neutral-900 transition font-medium border rounded text-xs text-white mr-2">#{tag}</button>
))}
</div>
</div>
Expand Down
56 changes: 56 additions & 0 deletions pages/[username]/random.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { GetServerSideProps } from "next";
import { getSession } from "next-auth/react";
import { userModel } from "../../models/models";
import getLookup from "../../utils/getLookup";
import { ssrRedirect } from "next-response-helpers";

export default function Random() {
return (
<></>
)
}

export const getServerSideProps: GetServerSideProps = async (context) => {
if (Array.isArray(context.params.username) || context.params.username.substring(0, 1) !== "@") return { notFound: true };

const username: string = context.params.username.substring(1);

const pageUserArr = await userModel.aggregate([
{$match: {urlName: username}},
getLookup("users", "_id", "following", "followingArr"),
getLookup("users", "email", "followers", "followersArr"),
{
$lookup: {
from: "updates",
as: "updatesArr",
let: {userId: "$_id"},
pipeline: [
{$match: {$expr: {$eq: ["$userId", "$$userId"]}}},
{$sample: {size: 1}},
],
}
}
]);

const pageUser = pageUserArr[0];

console.log(pageUser);

if (!pageUser) return {notFound: true};

const session = await getSession(context);
const thisUser = session ? await userModel.findOne({email: session.user.email}) : null;

const isPrivate = (pageUser.truePrivate || pageUser.private);

const canAccess = (!isPrivate || (thisUser && (
// following user
pageUser.followers.includes(thisUser.email) ||
// or are the user
pageUser._id.toString() === thisUser._id.toString()
)));

if (!canAccess || !pageUser.updatesArr.length) return ssrRedirect(`/@${username}`);

return ssrRedirect(`/@${username}/${pageUser.updatesArr[0].url}`);
}
2 changes: 0 additions & 2 deletions utils/requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ export async function getUpdateRequest(username: string, url: string): Promise<G
getLookup("users", "_id", "mentionedUsers", "mentionedUsersArr"),
]);

console.log(user._id, url);

if (!updates.length) return null;


Expand Down

1 comment on commit 5568be2

@vercel
Copy link

@vercel vercel bot commented on 5568be2 Aug 18, 2023

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

updately – ./

updately-wwsalmon.vercel.app
updately-git-main-wwsalmon.vercel.app

Please sign in to comment.