Skip to content

Commit

Permalink
Merge Release 1.18.0
Browse files Browse the repository at this point in the history
  • Loading branch information
sharunkumar committed Oct 28, 2023
2 parents 3008ae4 + d795a59 commit 9c60525
Show file tree
Hide file tree
Showing 51 changed files with 649 additions and 176 deletions.
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ android {
applicationId "app.vger.voyager"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 164
versionName "1.17.1"
versionCode 165
versionName "1.18.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
Expand Down
4 changes: 2 additions & 2 deletions ios/App/App/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.17.1</string>
<string>1.18.0</string>
<key>CFBundleVersion</key>
<string>164</string>
<string>165</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "voyager",
"description": "A progressive webapp Lemmy client",
"private": true,
"version": "1.17.1",
"version": "1.18.0",
"type": "module",
"packageManager": "pnpm@8.9.2+sha256.8d62573d93061f2722b7b48c9739e96cd4603c3ab153bc81c619dcb9861a214e",
"scripts": {
Expand Down
23 changes: 21 additions & 2 deletions src/TabbedRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ export default function TabbedRoutes() {
const isInboxButtonDisabled = location.pathname.startsWith("/inbox");
const isProfileButtonDisabled = location.pathname.startsWith("/profile");
const isSearchButtonDisabled = location.pathname.startsWith("/search");
const isSettingsButtonDisabled = location.pathname.startsWith("/settings");

async function onPostsClick() {
if (!isPostsButtonDisabled) return;
Expand Down Expand Up @@ -178,7 +179,12 @@ export default function TabbedRoutes() {
async function onInboxClick() {
if (!isInboxButtonDisabled) return;

if (scrollUpIfNeeded(activePageRef?.current)) return;
if (
// Messages are in reverse order, so bail on scroll up
!location.pathname.startsWith("/inbox/messages/") &&
scrollUpIfNeeded(activePageRef?.current)
)
return;

router.push(`/inbox`, "back");
}
Expand All @@ -202,6 +208,14 @@ export default function TabbedRoutes() {
router.push(`/search`, "back");
}

async function onSettingsClick() {
if (!isSettingsButtonDisabled) return;

if (scrollUpIfNeeded(activePageRef?.current)) return;

router.push(`/settings`, "back");
}

function buildGeneralBrowseRoutes(tab: string) {
return [
// eslint-disable-next-line react/jsx-key
Expand Down Expand Up @@ -498,12 +512,17 @@ export default function TabbedRoutes() {
<IonLabel>Search</IonLabel>
<Interceptor onClick={onSearchClick} />
</IonTabButton>
<IonTabButton tab="settings" href="/settings">
<IonTabButton
tab="settings"
href="/settings"
disabled={isSettingsButtonDisabled}
>
<IonIcon aria-hidden="true" icon={cog} />
<IonLabel>Settings</IonLabel>
{settingsNotificationCount ? (
<IonBadge color="danger">{settingsNotificationCount}</IonBadge>
) : undefined}
<Interceptor onClick={onSettingsClick} />
</IonTabButton>
</IonTabBar>
</IonTabs>
Expand Down
21 changes: 14 additions & 7 deletions src/features/auth/authSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,13 +230,7 @@ export const getSiteIfNeeded =

export const getSite =
() => async (dispatch: AppDispatch, getState: () => RootState) => {
const jwtPayload = jwtPayloadSelector(getState());
const instance = jwtPayload?.iss ?? getState().auth.connectedInstance;

const details = await getClient(
instance,
jwtSelector(getState()),
).getSite();
const details = await clientSelector(getState()).getSite();

dispatch(updateUserDetails(details));
};
Expand Down Expand Up @@ -368,3 +362,16 @@ function updateApplicationContextIfNeeded(
: "",
});
}

export const blockInstance =
(block: boolean, id: number) =>
async (dispatch: AppDispatch, getState: () => RootState) => {
if (!id) return;

await clientSelector(getState())?.blockInstance({
instance_id: id,
block,
});

await dispatch(getSite());
};
11 changes: 10 additions & 1 deletion src/features/comment/CommentEllipsis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ import {
share,
} from "../../helpers/lemmy";
import { useBuildGeneralBrowseLink } from "../../helpers/routes";
import { saveError, saveSuccess, voteError } from "../../helpers/toastMessages";
import {
postLocked,
saveError,
saveSuccess,
voteError,
} from "../../helpers/toastMessages";
import { useAppDispatch, useAppSelector } from "../../store";
import { PageContext } from "../auth/PageContext";
import { handleSelector, isDownvoteEnabledSelector } from "../auth/authSlice";
Expand Down Expand Up @@ -197,6 +202,10 @@ export default function MoreActions({
handler: () => {
(async () => {
if (presentLoginIfNeeded()) return;
if (commentView.post.locked) {
presentToast(postLocked);
return;
}

const reply = await presentCommentReply(commentView);

Expand Down
7 changes: 3 additions & 4 deletions src/features/comment/CommentTree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,14 @@ export default function CommentTree({
rootIndex,
}: CommentTreeProps) {
const dispatch = useAppDispatch();
const commentCollapsedById = useAppSelector(
(state) => state.comment.commentCollapsedById,
const collapsed = useAppSelector(
(state) =>
state.comment.commentCollapsedById[comment.comment_view.comment.id],
);
const { tapToCollapse } = useAppSelector(
(state) => state.settings.general.comments,
);

const collapsed = commentCollapsedById[comment.comment_view.comment.id];

// Comment context chains don't show missing for parents
const showMissing = useMemo(() => {
if (!highlightedCommentId) return true;
Expand Down
7 changes: 4 additions & 3 deletions src/features/labels/Vote.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { isDownvoteEnabledSelector } from "../auth/authSlice";
import { ImpactStyle } from "@capacitor/haptics";
import useHapticFeedback from "../../helpers/useHapticFeedback";
import useAppToast from "../../helpers/useAppToast";
import { formatNumber } from "../../helpers/number";

const Container = styled.div<{
vote?: 1 | -1 | 0;
Expand Down Expand Up @@ -105,7 +106,7 @@ export default function Vote({ item }: VoteProps): React.ReactElement {
await onVote(e, myVote === 1 ? 0 : 1);
}}
>
<IonIcon icon={arrowUpSharp} /> {upvotes}
<IonIcon icon={arrowUpSharp} /> {formatNumber(upvotes)}
</Container>
<Container
vote={myVote}
Expand All @@ -114,7 +115,7 @@ export default function Vote({ item }: VoteProps): React.ReactElement {
await onVote(e, myVote === -1 ? 0 : -1);
}}
>
<IonIcon icon={arrowDownSharp} /> {downvotes}
<IonIcon icon={arrowDownSharp} /> {formatNumber(downvotes)}
</Container>
</>
);
Expand All @@ -141,7 +142,7 @@ export default function Vote({ item }: VoteProps): React.ReactElement {
}}
>
<IonIcon icon={myVote === -1 ? arrowDownSharp : arrowUpSharp} />{" "}
{score}
{formatNumber(score)}
</Container>
);
}
Expand Down
7 changes: 6 additions & 1 deletion src/features/labels/links/PersonLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,12 @@ export default function PersonLink({
item={person}
showInstanceWhenRemote={showInstanceWhenRemote || forceInstanceUrl}
/>
{showBadge && <AgeBadge published={person.published} />}
{showBadge && (
<>
{person.bot_account && " 🤖"}
<AgeBadge published={person.published} />
</>
)}
</StyledLink>
);
}
48 changes: 48 additions & 0 deletions src/features/post/detail/Locked.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import styled from "@emotion/styled";
import { IonIcon } from "@ionic/react";
import { lockClosed } from "ionicons/icons";

const Container = styled.div`
display: flex;
align-items: center;
gap: 16px;
margin-top: 8px;
padding-top: 8px;
margin-bottom: -8px;
border-top: 1px solid
var(
--ion-item-border-color,
var(--ion-border-color, var(--ion-color-step-250, #c8c7cc))
);
`;

const LockIcon = styled(IonIcon)`
font-size: 32px;
margin-left: 8px;
`;

const Description = styled.div`
font-size: 0.8725rem;
font-weight: 500;
color: var(--ion-color-medium);
aside {
font-size: 0.8125rem;
font-weight: normal;
opacity: 0.8;
}
`;

export default function Locked() {
return (
<Container>
<LockIcon icon={lockClosed} color="success" />
<Description>
<div>Post Locked</div>
<aside>Moderators have turned off new comments.</aside>
</Description>
</Container>
);
}
9 changes: 9 additions & 0 deletions src/features/post/detail/PostDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ import PostGalleryImg from "../../gallery/PostGalleryImg";
import { scrollIntoView } from "../../../helpers/dom";
import JumpFab from "../../comment/JumpFab";
import { OTapToCollapseType } from "../../../services/db";
import Locked from "./Locked";
import useAppToast from "../../../helpers/useAppToast";
import { postLocked } from "../../../helpers/toastMessages";

const BorderlessIonItem = styled(IonItem)`
--padding-start: 0;
Expand Down Expand Up @@ -139,6 +142,7 @@ export default function PostDetail({
const { tapToCollapse } = useAppSelector(
(state) => state.settings.general.comments,
);
const presentToast = useAppToast();

const [viewAllCommentsSpace, setViewAllCommentsSpace] = useState(70); // px

Expand Down Expand Up @@ -239,6 +243,7 @@ export default function PostDetail({
<PersonLink person={post.creator} prefix="by" />
</By>
<Stats post={post} />
{post.post.locked && <Locked />}
</PostDeets>
</Container>
</BorderlessIonItem>
Expand All @@ -247,6 +252,10 @@ export default function PostDetail({
post={post}
onReply={async () => {
if (presentLoginIfNeeded()) return;
if (post.post.locked) {
presentToast(postLocked);
return;
}

const reply = await presentCommentReply(post);

Expand Down
3 changes: 2 additions & 1 deletion src/features/post/inFeed/PreviewStats.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { chatbubbleOutline, timeOutline } from "ionicons/icons";
import { PostView } from "lemmy-js-client";
import Ago from "../../labels/Ago";
import Vote from "../../labels/Vote";
import { formatNumber } from "../../../helpers/number";

const Container = styled.div`
display: flex;
Expand All @@ -20,7 +21,7 @@ export default function PreviewStats({ post }: PreviewStatsProps) {
<Container>
<Vote item={post} />
<IonIcon icon={chatbubbleOutline} />
{post.counts.comments}
{formatNumber(post.counts.comments)}
<IonIcon icon={timeOutline} />
<Ago date={post.post.published} />
</Container>
Expand Down
46 changes: 36 additions & 10 deletions src/features/post/shared/Embed.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
import { css } from "@emotion/react";
import styled from "@emotion/styled";
import { IonIcon } from "@ionic/react";
import { chevronForward, linkOutline } from "ionicons/icons";
import {
albumsOutline,
chatboxOutline,
chevronForward,
linkOutline,
peopleOutline,
personOutline,
} from "ionicons/icons";
import { PostView } from "lemmy-js-client";
import { MouseEvent, useState } from "react";
import { MouseEvent, useMemo, useState } from "react";
import { useAppDispatch, useAppSelector } from "../../../store";
import { isNsfwBlurred } from "../../labels/Nsfw";
import { setPostRead } from "../postSlice";
import InAppExternalLink from "../../shared/InAppExternalLink";
import LinkInterceptor from "../../shared/markdown/LinkInterceptor";
import useLemmyUrlHandler from "../../shared/useLemmyUrlHandler";

const Container = styled(InAppExternalLink)`
const Container = styled(LinkInterceptor)`
display: flex;
flex-direction: column;
Expand Down Expand Up @@ -76,21 +84,39 @@ interface EmbedProps {
export default function Embed({ post, className }: EmbedProps) {
const [error, setError] = useState(false);
const dispatch = useAppDispatch();
const blurNsfw = useAppSelector(
(state) => state.settings.appearance.posts.blurNsfw,
);
const { determineObjectTypeFromUrl } = useLemmyUrlHandler();

const icon = useMemo(() => {
const type = post.post.url
? determineObjectTypeFromUrl(post.post.url)
: undefined;

switch (type) {
case "comment":
return chatboxOutline;
case "community":
return peopleOutline;
case "post":
return albumsOutline;
case "user":
return personOutline;
case undefined:
return linkOutline;
}
}, [post.post.url, determineObjectTypeFromUrl]);

const handleLinkClick = (e: MouseEvent) => {
e.stopPropagation();
dispatch(setPostRead(post.post.id));
};
const blurNsfw = useAppSelector(
(state) => state.settings.appearance.posts.blurNsfw,
);

return (
<Container
className={className}
href={post.post.url}
target="_blank"
rel="noopener noreferrer"
onClick={handleLinkClick}
draggable="false"
>
Expand All @@ -103,7 +129,7 @@ export default function Embed({ post, className }: EmbedProps) {
/>
)}
<Bottom>
<EmbedIcon icon={linkOutline} />
<EmbedIcon icon={icon} />
<Divider />
<Url>{post.post.url}</Url>
<IonIcon icon={chevronForward} />
Expand Down
Loading

0 comments on commit 9c60525

Please sign in to comment.