Skip to content

Commit

Permalink
Merge Release 1.46.3
Browse files Browse the repository at this point in the history
  • Loading branch information
sharunkumar committed Mar 14, 2024
2 parents a094bc7 + cd50b4e commit 445353f
Show file tree
Hide file tree
Showing 18 changed files with 611 additions and 104 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 223
versionName "1.46.2"
versionCode 224
versionName "1.46.3"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
Expand Down
544 changes: 488 additions & 56 deletions android/app/src/main/AndroidManifest.xml

Large diffs are not rendered by default.

29 changes: 29 additions & 0 deletions android/app/src/main/java/app/vger/voyager/MainActivity.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package app.vger.voyager;

import android.app.AlertDialog;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.webkit.URLUtil;

import com.getcapacitor.BridgeActivity;

Expand Down Expand Up @@ -35,4 +39,29 @@ protected void onCreate(Bundle savedInstanceState) {
getWindow().setNavigationBarColor(0);
}
}

@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);

if (intent.getAction() == Intent.ACTION_SEND) {
var newIntent = new Intent(Intent.ACTION_VIEW);
var potentialUrl = intent.getStringExtra(Intent.EXTRA_TEXT);

if (!URLUtil.isValidUrl(potentialUrl) || !potentialUrl.startsWith("https://")) {
new AlertDialog.Builder(bridge.getContext())
.setTitle("Unknown share data received")
.setMessage("Voyager only accepts URLs to Lemmy content so that you can browse in-app.")
.setCancelable(true)
.setPositiveButton("OK", null)
.show();

return;
}

newIntent.setData(Uri.parse(potentialUrl));

bridge.onNewIntent(newIntent);
}
}
}
1 change: 1 addition & 0 deletions android/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
<string name="title_activity_main">Voyager</string>
<string name="package_name">app.vger.voyager</string>
<string name="custom_url_scheme">app.vger.voyager</string>
<string name="lemmy_link">Lemmy link</string>
</resources>
4 changes: 2 additions & 2 deletions ios/App/App.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@
INFOPLIST_FILE = VoyagerActionExtension/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Open in Voyager";
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MARKETING_VERSION = 1.0;
Expand Down Expand Up @@ -695,7 +695,7 @@
INFOPLIST_FILE = VoyagerActionExtension/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Open in Voyager";
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MARKETING_VERSION = 1.0;
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,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.46.2</string>
<string>1.46.3</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
Expand All @@ -32,7 +32,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>223</string>
<string>224</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSRequiresIPhoneOS</key>
Expand Down
20 changes: 10 additions & 10 deletions ios/App/VoyagerActionExtension/ActionRequestHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,18 @@ final class ActionRequestHandler: NSObject, NSExtensionRequestHandling, Sendable
}

extension URL {
var isPotentialLemmyInstance: Bool {
get async {
do {
guard host() != nil else {
throw ActionRequestHandler.Error.noHost
var isPotentialLemmyInstance: Bool {
get async {
do {
guard let host = self.host else {
throw ActionRequestHandler.Error.noHost
}
return true
} catch {
return false
}
}
return true
} catch {
return false
}
}
}

var iceCubesAppDeepLink: URL {
var components = URLComponents(url: self, resolvingAgainstBaseURL: false)!
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.46.2",
"version": "1.46.3",
"type": "module",
"packageManager": "pnpm@8.15.4+sha256.cea6d0bdf2de3a0549582da3983c70c92ffc577ff4410cbf190817ddc35137c2",
"scripts": {
Expand Down
20 changes: 17 additions & 3 deletions src/features/comment/compose/edit/CommentEdit.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { IonButtons, IonButton, IonToolbar, IonTitle } from "@ionic/react";
import {
IonButtons,
IonButton,
IonToolbar,
IonTitle,
IonIcon,
} from "@ionic/react";
import { Comment } from "lemmy-js-client";
import { useEffect, useState } from "react";
import { useAppDispatch } from "../../../../store";
Expand All @@ -9,6 +15,8 @@ import CommentEditorContent from "../CommentEditorContent";
import useAppToast from "../../../../helpers/useAppToast";
import AppHeader from "../../../shared/AppHeader";
import { clearRecoveredText } from "../../../../helpers/useTextRecovery";
import { isIosTheme } from "../../../../helpers/device";
import { arrowBackSharp, send } from "ionicons/icons";

type CommentEditingProps = DismissableProps & {
item: Comment;
Expand Down Expand Up @@ -67,7 +75,13 @@ export default function CommentEdit({
<AppHeader>
<IonToolbar>
<IonButtons slot="start">
<IonButton onClick={() => dismiss()}>Cancel</IonButton>
<IonButton onClick={() => dismiss()}>
{isIosTheme() ? (
"Cancel"
) : (
<IonIcon icon={arrowBackSharp} slot="icon-only" />
)}
</IonButton>
</IonButtons>
<IonTitle>
<Centered>
Expand All @@ -83,7 +97,7 @@ export default function CommentEdit({
color={isSubmitDisabled ? "medium" : undefined}
onClick={submit}
>
Save
{isIosTheme() ? "Save" : <IonIcon icon={send} slot="icon-only" />}
</IonButton>
</IonButtons>
</IonToolbar>
Expand Down
7 changes: 4 additions & 3 deletions src/features/comment/compose/reply/CommentReply.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ import { isLemmyError } from "../../../../helpers/lemmy";
import AccountSwitcher from "../../../auth/AccountSwitcher";
import { getClient } from "../../../../services/lemmy";
import AppHeader from "../../../shared/AppHeader";
import { arrowBackSharp } from "ionicons/icons";
import { arrowBackSharp, send } from "ionicons/icons";
import { isIosTheme } from "../../../../helpers/device";

export const UsernameIonText = styled(IonText)`
font-size: 0.7em;
Expand Down Expand Up @@ -239,7 +240,7 @@ export default function CommentReply({
<IonToolbar>
<IonButtons slot="start">
<IonButton onClick={() => dismiss()}>
{document.documentElement.classList.contains("ios") ? (
{isIosTheme() ? (
"Cancel"
) : (
<IonIcon icon={arrowBackSharp} slot="icon-only" />
Expand Down Expand Up @@ -280,7 +281,7 @@ export default function CommentReply({
color={isSubmitDisabled ? "medium" : undefined}
onClick={submit}
>
Post
{isIosTheme() ? "Post" : <IonIcon icon={send} slot="icon-only" />}
</IonButton>
</IonButtons>
</IonToolbar>
Expand Down
11 changes: 9 additions & 2 deletions src/features/community/titleSearch/TitleSearch.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { IonButton, IonButtons, IonIcon, IonTitle } from "@ionic/react";
import { chevronDown } from "ionicons/icons";
import { chevronDown, close } from "ionicons/icons";
import React, { useContext, useEffect, useRef } from "react";
import { TitleSearchContext } from "./TitleSearchProvider";
import { styled } from "@linaria/react";
import { isIosTheme } from "../../../helpers/device";

const TitleContents = styled.span`
display: inline-flex;
Expand Down Expand Up @@ -82,7 +83,13 @@ export default function TitleSearch({ name, children }: TitleSearchProps) {
</IonTitle>

<IonButtons slot="end">
<IonButton onClick={() => setSearching(false)}>Cancel</IonButton>
<IonButton onClick={() => setSearching(false)}>
{isIosTheme() ? (
"Cancel"
) : (
<IonIcon icon={close} slot="icon-only" />
)}
</IonButton>
</IonButtons>
</>
);
Expand Down
5 changes: 4 additions & 1 deletion src/features/post/new/NewPostText.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
IonBackButton,
IonButton,
IonButtons,
IonIcon,
IonText,
IonTitle,
IonToolbar,
Expand All @@ -12,6 +13,8 @@ import { clearRecoveredText } from "../../../helpers/useTextRecovery";
import AppHeader from "../../shared/AppHeader";
import Editor from "../../shared/markdown/editing/Editor";
import { MarkdownEditorIonContent } from "../../shared/markdown/editing/MarkdownToolbar";
import { isIosTheme } from "../../../helpers/device";
import { send } from "ionicons/icons";

interface NewPostTextProps {
value: string;
Expand Down Expand Up @@ -70,7 +73,7 @@ export default function NewPostText({
onClick={submit}
disabled={isSubmitDisabled}
>
Post
{isIosTheme() ? "Post" : <IonIcon icon={send} slot="icon-only" />}
</IonButton>
</IonButtons>
</IonToolbar>
Expand Down
14 changes: 4 additions & 10 deletions src/features/shared/HeaderEllipsisIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
import { IonIcon } from "@ionic/react";
import { css, cx } from "@linaria/core";
import { ellipsisHorizontal } from "ionicons/icons";
import { ellipsisHorizontal, ellipsisVertical } from "ionicons/icons";
import { ComponentProps } from "react";

const rotateCss = css`
&.md {
transform: rotate(90deg);
}
`;
import { isIosTheme } from "../../helpers/device";

export default function HeaderEllipsisIcon(
props: ComponentProps<typeof IonIcon>,
) {
return (
<IonIcon
{...props}
icon={ellipsisHorizontal}
className={cx(rotateCss, props.className)}
icon={isIosTheme() ? ellipsisHorizontal : ellipsisVertical}
className={props.className}
/>
);
}
21 changes: 16 additions & 5 deletions src/features/shared/markdown/editing/PreviewModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
IonButton,
IonButtons,
IonContent,
IonIcon,
IonPage,
IonTitle,
IonToolbar,
Expand All @@ -10,6 +11,8 @@ import Markdown from "../Markdown";
import CommentMarkdown from "../../../comment/CommentMarkdown";
import AppHeader from "../../AppHeader";
import { useId } from "react";
import { isIosTheme } from "../../../../helpers/device";
import { arrowBackSharp } from "ionicons/icons";

interface PreviewModalProps {
text: string;
Expand Down Expand Up @@ -49,11 +52,19 @@ export default function PreviewModal({
<IonPage>
<AppHeader>
<IonToolbar>
<IonButtons slot="end">
<IonButton color="primary" strong onClick={() => onDismiss()}>
Done
</IonButton>
</IonButtons>
{isIosTheme() ? (
<IonButtons slot="primary">
<IonButton strong onClick={() => onDismiss()}>
Done
</IonButton>
</IonButtons>
) : (
<IonButtons slot="start">
<IonButton onClick={() => onDismiss()}>
<IonIcon icon={arrowBackSharp} slot="icon-only" />
</IonButton>
</IonButtons>
)}
<IonTitle>Preview</IonTitle>
</IonToolbar>
</AppHeader>
Expand Down
5 changes: 5 additions & 0 deletions src/helpers/device.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import UAParser from "ua-parser-js";
import { Capacitor } from "@capacitor/core";
import { NavMode, NavModes } from "capacitor-android-nav-mode";
import { memoize } from "lodash";

export function isNative() {
return Capacitor.isNativePlatform();
Expand Down Expand Up @@ -62,3 +63,7 @@ export function getAndroidNavMode() {
androidNavMode = promise;
return promise;
}

export const isIosTheme = memoize(() =>
document.documentElement.classList.contains("ios"),
);
3 changes: 2 additions & 1 deletion src/helpers/toastMessages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,8 @@ export const cacheClearFailed: AppToastOptions = {
};

export const deepLinkFailed: AppToastOptions = {
message: "Failed to find requested link on your instance",
message:
"Unknown URL. Voyager only accepts URLs to Lemmy content to browse in-app.",
color: "warning",
position: "top",
duration: 7000,
Expand Down
11 changes: 9 additions & 2 deletions src/routes/pages/profile/ProfilePage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
IonButton,
IonButtons,
IonIcon,
IonPage,
IonTitle,
IonToolbar,
Expand All @@ -19,6 +20,8 @@ import FeedContent from "../shared/FeedContent";
import ProfilePageActions from "../../../features/user/ProfilePageActions";
import { useSetActivePage } from "../../../features/auth/AppContext";
import AppHeader from "../../../features/shared/AppHeader";
import { swapHorizontalSharp } from "ionicons/icons";
import { isIosTheme } from "../../../helpers/device";

export default function ProfilePage() {
const pageRef = useRef<HTMLElement>(null);
Expand All @@ -39,9 +42,13 @@ export default function ProfilePage() {
<AppHeader>
<IonToolbar>
{!accountsListEmpty && (
<IonButtons slot="start">
<IonButtons slot="secondary">
<IonButton onClick={() => presentAccountSwitcher()}>
Accounts
{isIosTheme() ? (
"Accounts"
) : (
<IonIcon icon={swapHorizontalSharp} slot="icon-only" />
)}
</IonButton>
</IonButtons>
)}
Expand Down
Loading

0 comments on commit 445353f

Please sign in to comment.