mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-26 10:45:57 +08:00
feat(ios): upgrade button in setting (#13645)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - New Features - Added a Subscription section in Mobile Settings (for signed-in users) with plan info and an Upgrade button that opens the native paywall. - Supports showing “Pro” and “AI” paywalls. - Integrated native paywall provider on iOS. - Style - Introduced new styling for the subscription card, content, and button. - Localization - Added English strings for subscription title, description, and button. - Chores - Minor iOS project cleanup and internal wiring to enable the paywall module. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -12,6 +12,7 @@ import { AppearanceGroup } from './appearance';
|
||||
import { ExperimentalFeatureSetting } from './experimental';
|
||||
import { OthersGroup } from './others';
|
||||
import * as styles from './style.css';
|
||||
import { UserSubscription } from './subscription';
|
||||
import { SwipeDialog } from './swipe-dialog';
|
||||
import { UserProfile } from './user-profile';
|
||||
import { UserUsage } from './user-usage';
|
||||
@@ -23,6 +24,7 @@ const MobileSetting = () => {
|
||||
return (
|
||||
<div className={styles.root}>
|
||||
<UserProfile />
|
||||
<UserSubscription />
|
||||
<UserUsage />
|
||||
<AppearanceGroup />
|
||||
<AboutGroup />
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
import { Button } from '@affine/component';
|
||||
import { AuthService, ServerService } from '@affine/core/modules/cloud';
|
||||
import { NativePaywallService } from '@affine/core/modules/paywall';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { useLiveData, useService } from '@toeverything/infra';
|
||||
|
||||
import * as styles from './styles.css';
|
||||
|
||||
export const UserSubscription = () => {
|
||||
const serverService = useService(ServerService);
|
||||
const authService = useService(AuthService);
|
||||
const nativePaywallProvider =
|
||||
useService(NativePaywallService).getNativePaywallProvider();
|
||||
const t = useI18n();
|
||||
|
||||
const supported = useLiveData(
|
||||
serverService.server.features$.map(f => f.payment)
|
||||
);
|
||||
|
||||
const loggedIn = useLiveData(authService.session.status$) === 'authenticated';
|
||||
|
||||
if (!loggedIn) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!supported) {
|
||||
// TODO: enable this
|
||||
// return null;
|
||||
}
|
||||
|
||||
if (!nativePaywallProvider) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.root}>
|
||||
<div className={styles.content}>
|
||||
<div className={styles.title}>
|
||||
{t['com.affine.payment.subscription.title']()}
|
||||
</div>
|
||||
<div className={styles.description}>
|
||||
{t['com.affine.payment.subscription.description']()}
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
className={styles.button}
|
||||
variant="primary"
|
||||
onClick={() =>
|
||||
void nativePaywallProvider.showPaywall('Pro').catch(console.error)
|
||||
}
|
||||
>
|
||||
{t['com.affine.payment.subscription.button']()}
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
import { cssVarV2 } from '@toeverything/theme/v2';
|
||||
import { style } from '@vanilla-extract/css';
|
||||
|
||||
export const root = style({
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: 16,
|
||||
border: `1px solid ${cssVarV2('database/border')}`,
|
||||
borderRadius: '12px',
|
||||
padding: '10px 16px',
|
||||
backgroundColor: cssVarV2('edgeless/selection/selectionMarqueeBackground'),
|
||||
});
|
||||
|
||||
export const content = style({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: 4,
|
||||
});
|
||||
|
||||
export const title = style({
|
||||
fontSize: '17px',
|
||||
lineHeight: '22px',
|
||||
fontWeight: 600,
|
||||
color: cssVarV2('text/primary'),
|
||||
});
|
||||
|
||||
export const description = style({
|
||||
fontSize: '13px',
|
||||
lineHeight: '18px',
|
||||
fontWeight: 400,
|
||||
color: cssVarV2('text/secondary'),
|
||||
});
|
||||
|
||||
export const button = style({
|
||||
fontSize: '15px',
|
||||
});
|
||||
@@ -44,6 +44,7 @@ import { configureNavigationPanelModule } from './navigation-panel';
|
||||
import { configureNotificationModule } from './notification';
|
||||
import { configureOpenInApp } from './open-in-app';
|
||||
import { configureOrganizeModule } from './organize';
|
||||
import { configurePaywallModule } from './paywall';
|
||||
import { configurePDFModule } from './pdf';
|
||||
import { configurePeekViewModule } from './peek-view';
|
||||
import { configurePermissionsModule } from './permissions';
|
||||
@@ -130,4 +131,5 @@ export function configureCommonModules(framework: Framework) {
|
||||
configureIndexerEmbeddingModule(framework);
|
||||
configureCommentModule(framework);
|
||||
configureDocSummaryModule(framework);
|
||||
configurePaywallModule(framework);
|
||||
}
|
||||
|
||||
10
packages/frontend/core/src/modules/paywall/index.ts
Normal file
10
packages/frontend/core/src/modules/paywall/index.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import type { Framework } from '@toeverything/infra';
|
||||
|
||||
import { NativePaywallService } from './services/native-paywall';
|
||||
|
||||
export { NativePaywallProvider } from './providers/native-paywall';
|
||||
export { NativePaywallService } from './services/native-paywall';
|
||||
|
||||
export function configurePaywallModule(framework: Framework) {
|
||||
framework.service(NativePaywallService);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { createIdentifier } from '@toeverything/infra';
|
||||
|
||||
export interface NativePaywallProvider {
|
||||
showPaywall(type: 'Pro' | 'AI'): Promise<void>;
|
||||
}
|
||||
|
||||
export const NativePaywallProvider = createIdentifier<NativePaywallProvider>(
|
||||
'NativePaywallProvider'
|
||||
);
|
||||
@@ -0,0 +1,13 @@
|
||||
import { Service } from '@toeverything/infra';
|
||||
|
||||
import { NativePaywallProvider } from '../providers/native-paywall';
|
||||
|
||||
export class NativePaywallService extends Service {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
getNativePaywallProvider() {
|
||||
return this.framework.getOptional(NativePaywallProvider);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user