feat: new domain folo.is

This commit is contained in:
DIYgod 2025-07-03 13:13:20 +08:00
parent 63d3df515b
commit d14c8f5c51
No known key found for this signature in database
24 changed files with 141 additions and 43 deletions

View File

@ -5,7 +5,7 @@ on:
# Do not use secrets or variables to allow for public access
env:
VITE_WEB_URL: https://app.follow.is
VITE_WEB_URL: https://app.folo.is
VITE_API_URL: https://api.follow.is
name: CI Format, Typecheck and Lint

View File

@ -28,7 +28,7 @@ For a more convenient development experience, we recommend developing in the bro
cd apps/desktop && pnpm run dev:web
```
This will open the browser at `https://app.follow.is/__debug_proxy`, allowing you to access the online API environment for development and debugging.
This will open the browser at `https://app.folo.is/__debug_proxy`, allowing you to access the online API environment for development and debugging.
### Develop in Electron

View File

@ -45,7 +45,7 @@ Feel free to try it using the following methods:
| Operating System | Source |
| :--------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Any | <a href="https://app.follow.is" target="_blank"><img src="https://github.com/user-attachments/assets/51ef7800-b683-4493-83e8-eb4752366997" alt="Browser" height="55"/></a> |
| Any | <a href="https://app.folo.is" target="_blank"><img src="https://github.com/user-attachments/assets/51ef7800-b683-4493-83e8-eb4752366997" alt="Browser" height="55"/></a> |
| iOS | <a href="https://apps.apple.com/us/app/folo-follow-everything/id6739802604" target="_blank"><img src="https://github.com/user-attachments/assets/a94d8698-2a11-4f43-9b0a-b756b17b61f7" alt="App Store" height="55"/></a> |
| Android | <a href="https://play.google.com/store/apps/details?id=is.follow" target="_blank"><img src="https://github.com/user-attachments/assets/0d178e0b-3ace-4f75-bbde-ab3c0a416ce8" alt="Google Play" height="55"/></a> <a href="https://github.com/RSSNext/Folo/releases/latest" target="_blank"><img src="https://github.com/user-attachments/assets/cf61e197-d756-4606-a8ad-fb591f79fdfc" alt="App Store" height="55"/></a> |
| macOS | <a href="https://apps.apple.com/us/app/folo-follow-everything/id6739802604" target="_blank"><img src="https://github.com/user-attachments/assets/0d47f902-7fa3-494e-ad28-9ab11af5e6d4" alt="Microsoft Store" height="55"/></a> <a href="https://github.com/RSSNext/Folo/releases/latest" target="_blank"><img src="https://github.com/user-attachments/assets/cf61e197-d756-4606-a8ad-fb591f79fdfc" alt="App Store" height="55"/></a> |

View File

@ -61,9 +61,9 @@ async function purgeCloudflareCache() {
const apiUrl = `https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/purge_cache`
const manifestPath = await fetch(
`https://app.follow.is/assets/manifest.txt?t=${Date.now()}`,
).then((res) => res.text())
const manifestPath = await fetch(`https://app.folo.is/assets/manifest.txt?t=${Date.now()}`).then(
(res) => res.text(),
)
try {
await fetch(apiUrl, {
@ -79,7 +79,7 @@ async function purgeCloudflareCache() {
console.info("Successfully purged Cloudflare cache")
} catch {
console.error("Failed to purge Cloudflare cache by tags, fallback to purge by files")
const allPath = manifestPath.split("\n").map((path) => `https://app.follow.is/${path}`)
const allPath = manifestPath.split("\n").map((path) => `https://app.folo.is/${path}`)
// Function to delay execution
const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))

View File

@ -190,7 +190,7 @@ const config: ForgeConfig = {
new MakerSquirrel({
name: "Folo",
setupIcon: isStaging ? "resources/icon-staging.ico" : "resources/icon.ico",
iconUrl: "https://app.follow.is/favicon.ico",
iconUrl: "https://app.folo.is/favicon.ico",
}),
new MakerAppImage({
config: {

View File

@ -26,5 +26,5 @@ export const getTrayIconPath = () => {
}
export const filePathToAppUrl = (filePath: string) => {
return `app://follow.is${pathToFileURL(filePath).pathname}`
return `app://folo.is${pathToFileURL(filePath).pathname}`
}

View File

@ -21,13 +21,13 @@
<meta name="apple-itunes-app" content="app-id=6739802604" />
<meta property="og:type" content="website" />
<meta property="og:title" content="Folo" />
<meta property="og:url" content="https://app.follow.is" />
<meta property="og:image" content="https://app.follow.is/og-image.png" />
<meta property="og:url" content="https://app.folo.is" />
<meta property="og:image" content="https://app.folo.is/og-image.png" />
<meta property="og:description" content="Your Self-custodial Feeds." />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Folo" />
<meta name="twitter:image" content="https://app.follow.is/og-image.png" />
<meta name="twitter:image" content="https://app.folo.is/og-image.png" />
<!-- Check Browser Script Inject -->
<script>

View File

@ -310,7 +310,7 @@ export const useFeedActions = ({
disabled: isEntryList,
click: () => {
copyToClipboard(
`https://badge.follow.is/feed/${feedId}?color=FF5C00&labelColor=black&style=flat-square`,
`https://badge.folo.is/feed/${feedId}?color=FF5C00&labelColor=black&style=flat-square`,
)
},
}),

View File

@ -47,32 +47,32 @@ const achievementActionIdMetaMap: Record<
[AchievementsActionIdMap.FIRST_CLAIM_FEED]: {
title: "achievement.first_claim_feed",
description: "achievement.first_claim_feed_description",
video: "https://assets.follow.is/FeedOwnerBadge.webm",
video: "https://assets.folo.is/FeedOwnerBadge.webm",
},
[AchievementsActionIdMap.FIRST_CREATE_LIST]: {
title: "achievement.first_create_list",
description: "achievement.first_create_list_description",
video: "https://assets.follow.is/ListBadge.webm",
video: "https://assets.folo.is/ListBadge.webm",
},
[AchievementsActionIdMap.LIST_SUBSCRIBE_50]: {
title: "achievement.list_subscribe_50",
description: "achievement.list_subscribe_50_description",
video: "https://assets.follow.is/50Subs.webm",
video: "https://assets.folo.is/50Subs.webm",
},
[AchievementsActionIdMap.LIST_SUBSCRIBE_100]: {
title: "achievement.list_subscribe_100",
description: "achievement.list_subscribe_100_description",
video: "https://assets.follow.is/100Subs.webm",
video: "https://assets.folo.is/100Subs.webm",
},
[AchievementsActionIdMap.LIST_SUBSCRIBE_500]: {
title: "achievement.list_subscribe_500",
description: "achievement.list_subscribe_500_description",
video: "https://assets.follow.is/500Subs.webm",
video: "https://assets.folo.is/500Subs.webm",
},
[AchievementsActionIdMap.PRODUCT_HUNT_VOTE]: {
title: "achievement.product_hunt_vote",
description: "achievement.product_hunt_vote_description",
video: "https://assets.follow.is/ProductHunt.webm",
video: "https://assets.folo.is/ProductHunt.webm",
},
// [AchievementsActionIdMap.FOLLOW_SPECIAL_FEED]: {
// title: "achievement.follow_special_feed",
@ -81,7 +81,7 @@ const achievementActionIdMetaMap: Record<
[AchievementsActionIdMap.ALPHA_TESTER]: {
title: "achievement.alpha_tester",
description: "achievement.alpha_tester_description",
video: "https://assets.follow.is/AlphaBadge.webm",
video: "https://assets.folo.is/AlphaBadge.webm",
},
[AchievementsActionIdMap.FEED_BOOSTER]: {
title: "achievement.feed_booster",

View File

@ -4,7 +4,7 @@ import { Button } from "@follow/components/ui/button/index.js"
export function DownloadPage() {
const openDownloadPage = () => {
window.open("https://follow.is/download", "_blank", "noopener,noreferrer")
window.open("https://folo.is/download", "_blank", "noopener,noreferrer")
}
return (

View File

@ -25,7 +25,7 @@ export const registerPusher = (self: ServiceWorkerGlobalScope) => {
case "new-entry": {
const notificationPromise = self.registration.showNotification(payload.title, {
body: payload.description,
icon: "https://app.follow.is/favicon.ico",
icon: "https://app.folo.is/favicon.ico",
data: {
type: payload.type,
feedId: payload.feedId,

View File

@ -37,9 +37,7 @@ const devPrint = (): PluginOption => ({
server.printUrls = () => {
_printUrls()
console.info(
` ${green("➜")} ${dim("Production debug")}: ${cyan(
"https://app.follow.is/__debug_proxy",
)}`,
` ${green("➜")} ${dim("Production debug")}: ${cyan("https://app.folo.is/__debug_proxy")}`,
)
console.info(
` ${green("➜")} ${dim("Development debug")}: ${cyan(
@ -313,7 +311,7 @@ function checkBrowserSupport() {
"Folo is not compatible with your browser because your browser version is too old. You can download and use the Folo app or continue using it with the latest browser.",
)
window.location.href = "https://follow.is/download"
window.location.href = "https://folo.is/download"
}
}

View File

@ -1,6 +1,6 @@
# Folo Mobile App 📱
This is the mobile client for [Folo](https://app.follow.is), built with [Expo](https://expo.dev). Folo organizes content into one timeline, keeping you updated on what matters, noise-free.
This is the mobile client for [Folo](https://app.folo.is), built with [Expo](https://expo.dev). Folo organizes content into one timeline, keeping you updated on what matters, noise-free.
## Features

View File

@ -6,7 +6,7 @@ import type { WebViewNavigation } from "react-native-webview"
import { openLink } from "../lib/native"
const allowHosts = new Set(["app.follow.is"])
const allowHosts = new Set(["app.follow.is", "app.folo.is"])
export function useWebViewNavigation({ webViewRef }: { webViewRef: RefObject<WebView> }) {
const onNavigationStateChange = useCallback(
(newNavState: WebViewNavigation) => {

View File

@ -6,7 +6,7 @@ export const op = new OpenPanel({
clientId: proxyEnv.OPENPANEL_CLIENT_ID ?? "",
apiUrl: proxyEnv.OPENPANEL_API_URL,
headers: {
Origin: "https://app.follow.is",
Origin: "https://app.folo.is",
},
sdk: "react-native",
sdkVersion: "1.0.0",

View File

@ -103,7 +103,7 @@ function ProfileScreenImpl(props: { userId: string }) {
const textLabelColor = useColor("label")
const openShareUrl = useCallback(() => {
if (!user?.id) return
const shareUrl = `https://app.follow.is/share/users/${user.id}`
const shareUrl = `https://app.folo.is/share/users/${user.id}`
Share.share({
message: shareUrl,
url: shareUrl,

View File

@ -1,4 +1,4 @@
export const siteConfig = {
repoUrl: "https://github.com/RSSNext/Follow",
appUrl: "https://app.follow.is",
appUrl: "https://app.folo.is",
}

View File

@ -18,7 +18,7 @@ const footerSections: FooterSection[] = [
{
title: "Product",
links: [
{ href: "https://follow.is", label: "Home", external: true },
{ href: "https://folo.is", label: "Home", external: true },
{ href: "https://github.com/RSSNext/folo", label: "GitHub", external: true },
{ href: "https://github.com/RSSNext/folo/releases", label: "Download", external: true },
],
@ -140,7 +140,7 @@ export const PoweredByFooter: Component = ({ className }) => (
</p>
<div className="flex items-center justify-center gap-4 md:justify-start">
<a
href="https://app.follow.is/privacy-policy"
href="https://app.folo.is/privacy-policy"
target="_blank"
rel="noopener noreferrer"
className="text-text-secondary hover:text-text text-xs transition-colors"
@ -148,7 +148,7 @@ export const PoweredByFooter: Component = ({ className }) => (
Privacy Policy
</a>
<a
href="https://app.follow.is/terms"
href="https://app.folo.is/terms"
target="_blank"
rel="noopener noreferrer"
className="text-text-secondary hover:text-text text-xs transition-colors"

View File

@ -2,7 +2,7 @@
**Effective Date:** 2025-05-15
At Folo, your personalized RSS reader and content hub, we are committed to protecting your privacy and handling your personal data responsibly. This Privacy Policy explains how Natural Selection Limited ("we," "us," or "Folo"), the operator of Folo, collects, uses, shares, stores, and protects your personal data when you use our application and related services (collectively, the "Service"). By using Folo, you agree to the practices described in this Privacy Policy and our [Terms of Service](https://app.follow.is/terms).
At Folo, your personalized RSS reader and content hub, we are committed to protecting your privacy and handling your personal data responsibly. This Privacy Policy explains how Natural Selection Limited ("we," "us," or "Folo"), the operator of Folo, collects, uses, shares, stores, and protects your personal data when you use our application and related services (collectively, the "Service"). By using Folo, you agree to the practices described in this Privacy Policy and our [Terms of Service](https://app.folo.is/terms).
This policy is designed to comply with Singapores Personal Data Protection Act (PDPA) and, where applicable, other data protection laws such as the European Unions General Data Protection Regulation (GDPR) and the California Consumer Privacy Act (CCPA). If you have any questions, please contact us at follow@rss3.io.
@ -120,7 +120,7 @@ When you use $POWER, we collect transaction data to facilitate rewards and preve
## 12. Updates to This Privacy Policy
We may update this Privacy Policy to reflect changes in our practices or legal requirements. We will notify you of significant changes (e.g., new data uses) at least 14 days in advance via email, in-app notification, or our website (https://app.follow.is). Continued use of the Service after updates constitutes acceptance. Check this page periodically for the latest version.
We may update this Privacy Policy to reflect changes in our practices or legal requirements. We will notify you of significant changes (e.g., new data uses) at least 14 days in advance via email, in-app notification, or our website (https://app.folo.is). Continued use of the Service after updates constitutes acceptance. Check this page periodically for the latest version.
## 13. Contact Us

View File

@ -32,7 +32,7 @@ You may not exploit the Service for commercial purposes unless explicitly author
## 5. Service Fees
Folo offers both free and paid features. Certain functionalities, such as advanced AI features or additional $POWER purchases, may require payment. All fees will be clearly disclosed in the application or on our website (https://app.follow.is). Fees are non-refundable unless required by applicable law.
Folo offers both free and paid features. Certain functionalities, such as advanced AI features or additional $POWER purchases, may require payment. All fees will be clearly disclosed in the application or on our website (https://app.folo.is). Fees are non-refundable unless required by applicable law.
## 6. Content and Intellectual Property
@ -82,7 +82,7 @@ To the fullest extent permitted by law, except where caused by our gross neglige
## 10. Modifications to the Terms
We may modify these Terms at any time. Changes take effect upon posting to the Service. For significant changes (e.g., affecting user rights, fees, or data use), we will notify you at least 14 days in advance via email, in-app notification, or our website (https://app.follow.is). If you disagree with the changes, you may terminate your account before they take effect by contacting us or using account settings. Continued use after changes constitutes acceptance. You are responsible for periodically reviewing the Terms.
We may modify these Terms at any time. Changes take effect upon posting to the Service. For significant changes (e.g., affecting user rights, fees, or data use), we will notify you at least 14 days in advance via email, in-app notification, or our website (https://app.folo.is). If you disagree with the changes, you may terminate your account before they take effect by contacting us or using account settings. Continued use after changes constitutes acceptance. You are responsible for periodically reviewing the Terms.
## 11. Termination
@ -106,4 +106,4 @@ Folo is an open-source project, and we welcome contributions such as bug reports
## 15. Privacy and Data Use
Folo takes your privacy seriously. We may collect, store, and process personal information, including usage patterns and content interactions. Our [Privacy Policy](https://app.follow.is/privacy-policy) will detail how we collect, process, and protect your data. Until available, contact follow@rss3.io for privacy inquiries. We are committed to handling your data securely and transparently in compliance with applicable laws, including Singapores Personal Data Protection Act.
Folo takes your privacy seriously. We may collect, store, and process personal information, including usage patterns and content interactions. Our [Privacy Policy](https://app.folo.is/privacy-policy) will detail how we collect, process, and protect your data. Until available, contact follow@rss3.io for privacy inquiries. We are committed to handling your data securely and transparently in compliance with applicable laws, including Singapores Personal Data Protection Act.

View File

@ -1,7 +1,7 @@
export const DEFAULT_VALUES = {
PROD: {
API_URL: "https://api.follow.is",
WEB_URL: "https://app.follow.is",
WEB_URL: "https://app.folo.is",
INBOXES_EMAIL: "@follow.re",
OPENPANEL_CLIENT_ID: "4382168f-b8d2-40c1-9a26-133a312d072b",
OPENPANEL_API_URL: "https://openpanel.follow.is/api",

View File

@ -30,8 +30,8 @@ export const createBuildSafeHeaders =
}
if (
(headers.Referer && headers.Referer !== "app://follow.is") ||
(headers.Origin && headers.Origin !== "app://follow.is")
(headers.Referer && headers.Referer !== "app://folo.is") ||
(headers.Origin && headers.Origin !== "app://folo.is")
) {
return headers
}

View File

@ -1,6 +1,6 @@
from mitmproxy import http
def request(flow: http.HTTPFlow) -> None:
if flow.request.pretty_host == "app.follow.is":
if flow.request.pretty_host == "app.folo.is":
flow.request.host = "localhost"
flow.request.port = 2233

View File

@ -109,6 +109,106 @@
}
]
},
{
"source": "/share/:path*",
"destination": "https://follow-external-ssr.vercel.app/share/:path*",
"has": [
{
"type": "host",
"value": "app.folo.is"
}
]
},
{
"source": "/og/:path*",
"destination": "https://follow-external-ssr.vercel.app/og/:path*",
"has": [
{
"type": "host",
"value": "app.folo.is"
}
]
},
{
"source": "/login",
"destination": "https://follow-external-ssr.vercel.app/login",
"has": [
{
"type": "host",
"value": "app.folo.is"
}
]
},
{
"source": "/register",
"destination": "https://follow-external-ssr.vercel.app/register",
"has": [
{
"type": "host",
"value": "app.folo.is"
}
]
},
{
"source": "/forget-password",
"destination": "https://follow-external-ssr.vercel.app/forget-password",
"has": [
{
"type": "host",
"value": "app.folo.is"
}
]
},
{
"source": "/reset-password",
"destination": "https://follow-external-ssr.vercel.app/reset-password",
"has": [
{
"type": "host",
"value": "app.folo.is"
}
]
},
{
"source": "/terms",
"destination": "https://follow-external-ssr.vercel.app/terms",
"has": [
{
"type": "host",
"value": "app.folo.is"
}
]
},
{
"source": "/privacy-policy",
"destination": "https://follow-external-ssr.vercel.app/privacy-policy",
"has": [
{
"type": "host",
"value": "app.folo.is"
}
]
},
{
"source": "/external-dist/:path*",
"destination": "https://follow-external-ssr.vercel.app/external-dist/:path*",
"has": [
{
"type": "host",
"value": "app.folo.is"
}
]
},
{
"source": "/dist-external/:path*",
"destination": "https://follow-external-ssr.vercel.app/dist-external/:path*",
"has": [
{
"type": "host",
"value": "app.folo.is"
}
]
},
{
"source": "/share/:path*",
"destination": "https://follow-external-ssr-dev.vercel.app/share/:path*",