176 lines
4.6 KiB
TypeScript
176 lines
4.6 KiB
TypeScript
import Taro from '@tarojs/taro';
|
|
import {
|
|
applyShareTitleTemplate,
|
|
DEFAULT_SHARE_DESC,
|
|
DEFAULT_SHARE_HINT,
|
|
DEFAULT_SHARE_TITLE,
|
|
resolveMiniShareRuntime,
|
|
type ClientRuntimeConfig,
|
|
type MiniShareRuntime,
|
|
type MiniShareSceneConfig,
|
|
} from '@dukang/shared-types';
|
|
import { toast } from './api';
|
|
import { getBrandAssetsSync, loadBrandAssets } from './brand-assets';
|
|
import { fetchClientConfig } from './pay-wechat';
|
|
|
|
export type ShareScene =
|
|
| 'home'
|
|
| 'stores'
|
|
| 'storeDetail'
|
|
| 'benefit'
|
|
| 'mine'
|
|
| 'productDetail'
|
|
| 'orderDetail';
|
|
|
|
export { DEFAULT_SHARE_TITLE, DEFAULT_SHARE_DESC };
|
|
|
|
export const WECHAT_SHARE_HINT = DEFAULT_SHARE_HINT;
|
|
|
|
const FALLBACK_SHARE: MiniShareRuntime = resolveMiniShareRuntime({});
|
|
|
|
let shareCached: MiniShareRuntime | null = null;
|
|
|
|
export function getShareRuntimeSync(): MiniShareRuntime {
|
|
return shareCached ?? FALLBACK_SHARE;
|
|
}
|
|
|
|
export function applyShareFromClientConfig(config?: ClientRuntimeConfig | null) {
|
|
if (config?.share) {
|
|
shareCached = config.share;
|
|
return shareCached;
|
|
}
|
|
return getShareRuntimeSync();
|
|
}
|
|
|
|
export async function loadShareConfig(force = false): Promise<MiniShareRuntime> {
|
|
if (!force && shareCached) return shareCached;
|
|
try {
|
|
const cfg = await fetchClientConfig();
|
|
if (cfg?.share) {
|
|
shareCached = cfg.share;
|
|
return shareCached;
|
|
}
|
|
} catch {
|
|
/* ignore */
|
|
}
|
|
shareCached = FALLBACK_SHARE;
|
|
return shareCached;
|
|
}
|
|
|
|
export function getDefaultShareImageUrl(): string {
|
|
const share = getShareRuntimeSync();
|
|
return share.default.imageUrl || getBrandAssetsSync().brandLogoUrl;
|
|
}
|
|
|
|
export function getShareHint(): string {
|
|
return getShareRuntimeSync().hint || DEFAULT_SHARE_HINT;
|
|
}
|
|
|
|
export function prefetchShareBrandAssets() {
|
|
void loadBrandAssets();
|
|
void loadShareConfig();
|
|
}
|
|
|
|
function sceneConfig(scene?: ShareScene): MiniShareSceneConfig {
|
|
const runtime = getShareRuntimeSync();
|
|
if (!scene) return runtime.default;
|
|
return runtime[scene] ?? runtime.default;
|
|
}
|
|
|
|
export type PageSharePayload = {
|
|
title?: string;
|
|
desc?: string;
|
|
path?: string;
|
|
imgUrl?: string;
|
|
link?: string;
|
|
};
|
|
|
|
export function buildSceneSharePayload(
|
|
scene: ShareScene,
|
|
options?: {
|
|
path?: string;
|
|
dynamicTitle?: string | null;
|
|
dynamicDesc?: string | null;
|
|
dynamicImageUrl?: string | null;
|
|
titleVars?: Record<string, string | undefined | null>;
|
|
},
|
|
): PageSharePayload {
|
|
const def = getShareRuntimeSync().default;
|
|
const sc = sceneConfig(scene);
|
|
const preferEntity = scene === 'productDetail' || scene === 'storeDetail';
|
|
|
|
let title: string;
|
|
if (preferEntity) {
|
|
title = (options?.dynamicTitle || '').trim() || def.title;
|
|
} else {
|
|
title = (sc.title || '').trim();
|
|
if (title && options?.titleVars) {
|
|
const vars = options.titleVars;
|
|
const missingRequired = Object.entries(vars).some(
|
|
([key, value]) => title.includes(`{${key}}`) && !(value != null && String(value).trim()),
|
|
);
|
|
title = missingRequired ? '' : applyShareTitleTemplate(title, vars);
|
|
}
|
|
if (!title) {
|
|
title = (options?.dynamicTitle || '').trim() || def.title;
|
|
}
|
|
}
|
|
|
|
const desc = (sc.desc || '').trim() || (options?.dynamicDesc || '').trim() || def.desc;
|
|
const imgUrl = preferEntity
|
|
? (options?.dynamicImageUrl || '').trim() || def.imageUrl || getDefaultShareImageUrl()
|
|
: (sc.imageUrl || '').trim() ||
|
|
(options?.dynamicImageUrl || '').trim() ||
|
|
def.imageUrl ||
|
|
getDefaultShareImageUrl();
|
|
|
|
return {
|
|
title,
|
|
desc,
|
|
path: options?.path,
|
|
imgUrl,
|
|
};
|
|
}
|
|
|
|
export async function applyWechatShare(): Promise<void> {
|
|
/* weapp 使用原生分享菜单,无 H5 JSSDK */
|
|
}
|
|
|
|
export async function handleShareButtonClick(
|
|
payload?: PageSharePayload,
|
|
): Promise<{ showGuide: boolean }> {
|
|
try {
|
|
await Taro.showShareMenu({
|
|
withShareTicket: true,
|
|
showShareItems: ['shareAppMessage', 'shareTimeline'],
|
|
});
|
|
} catch {
|
|
try {
|
|
await Taro.showShareMenu({ withShareTicket: true });
|
|
} catch {
|
|
/* ignore */
|
|
}
|
|
}
|
|
toast(getShareHint());
|
|
void payload;
|
|
return { showGuide: false };
|
|
}
|
|
|
|
export function toWeappShareMessage(payload?: PageSharePayload) {
|
|
const def = getShareRuntimeSync().default;
|
|
return {
|
|
title: payload?.title || def.title,
|
|
path: payload?.path || '/pages/home/index',
|
|
imageUrl: payload?.imgUrl || getDefaultShareImageUrl(),
|
|
};
|
|
}
|
|
|
|
export function toWeappShareTimeline(payload?: PageSharePayload, query = '') {
|
|
const def = getShareRuntimeSync().default;
|
|
return {
|
|
title: payload?.title || def.title,
|
|
query,
|
|
imageUrl: payload?.imgUrl || getDefaultShareImageUrl(),
|
|
};
|
|
}
|