feat: 添加设备振动功能,支持多种振动模式和反馈
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import type { Awaitable } from "@vueuse/core";
|
||||
import type { ChartOptions, DeepPartial, IChartApi, ISeriesApi, OhlcData, SeriesOptionsMap, SeriesType } from "lightweight-charts";
|
||||
import type { ChartOptions, DeepPartial, IChartApi, ISeriesApi, OhlcData, SeriesType } from "lightweight-charts";
|
||||
import { AreaSeries, BarSeries, BaselineSeries, CandlestickSeries, ColorType, createChart, HistogramSeries, LineSeries } from "lightweight-charts";
|
||||
import { mergeWith } from "lodash-es";
|
||||
|
||||
@@ -27,8 +27,8 @@ const initializeOptions: Required<TradingViewOptions> = {
|
||||
width: 400,
|
||||
height: 300,
|
||||
layout: {
|
||||
textColor: "white",
|
||||
background: { type: ColorType.Solid, color: "#000000" },
|
||||
textColor: "black",
|
||||
background: { type: ColorType.Solid, color: "#fff" },
|
||||
},
|
||||
},
|
||||
autosize: true,
|
||||
|
||||
116
src/composables/useVibrate.ts
Normal file
116
src/composables/useVibrate.ts
Normal file
@@ -0,0 +1,116 @@
|
||||
import { Capacitor } from "@capacitor/core";
|
||||
import { Haptics, ImpactStyle } from "@capacitor/haptics";
|
||||
|
||||
export interface HapticsOptions {
|
||||
/**
|
||||
* 振动强度
|
||||
* - light: 轻微振动
|
||||
* - medium: 中等振动
|
||||
* - heavy: 强烈振动
|
||||
*/
|
||||
impact?: ImpactStyle;
|
||||
/**
|
||||
* 振动时长 (毫秒)
|
||||
*/
|
||||
duration?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设备振动 Composable
|
||||
*/
|
||||
export function useHaptics() {
|
||||
/**
|
||||
* 检查设备是否支持振动
|
||||
*/
|
||||
const isHapticsAvailable = computed(() => {
|
||||
return Capacitor.isNativePlatform();
|
||||
});
|
||||
|
||||
/**
|
||||
* 触发振动反馈
|
||||
* @param options 振动配置选项
|
||||
*/
|
||||
async function vibrate(options: HapticsOptions = {}) {
|
||||
if (!isHapticsAvailable.value) {
|
||||
console.warn("Haptics not available on this platform");
|
||||
return;
|
||||
}
|
||||
|
||||
const { impact = ImpactStyle.Medium, duration } = options;
|
||||
|
||||
try {
|
||||
if (duration) {
|
||||
// 自定义时长振动
|
||||
await Haptics.vibrate({ duration });
|
||||
}
|
||||
else {
|
||||
// 触觉反馈振动
|
||||
await Haptics.impact({ style: impact });
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
console.error("Haptics error:", error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 轻微振动 (适用于按钮点击)
|
||||
*/
|
||||
async function lightVibrate() {
|
||||
await vibrate({ impact: ImpactStyle.Light });
|
||||
}
|
||||
|
||||
/**
|
||||
* 中等振动 (适用于选择操作)
|
||||
*/
|
||||
async function mediumVibrate() {
|
||||
await vibrate({ impact: ImpactStyle.Medium });
|
||||
}
|
||||
|
||||
/**
|
||||
* 强烈振动 (适用于重要通知)
|
||||
*/
|
||||
async function heavyVibrate() {
|
||||
await vibrate({ impact: ImpactStyle.Heavy });
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功振动模式
|
||||
*/
|
||||
async function successVibrate() {
|
||||
await lightVibrate();
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
await lightVibrate();
|
||||
}
|
||||
|
||||
/**
|
||||
* 错误振动模式
|
||||
*/
|
||||
async function errorVibrate() {
|
||||
await heavyVibrate();
|
||||
await new Promise(resolve => setTimeout(resolve, 200));
|
||||
await heavyVibrate();
|
||||
await new Promise(resolve => setTimeout(resolve, 200));
|
||||
await heavyVibrate();
|
||||
}
|
||||
|
||||
/**
|
||||
* 警告振动模式
|
||||
*/
|
||||
async function warningVibrate() {
|
||||
await mediumVibrate();
|
||||
await new Promise(resolve => setTimeout(resolve, 150));
|
||||
await mediumVibrate();
|
||||
}
|
||||
|
||||
return {
|
||||
isHapticsAvailable,
|
||||
vibrate,
|
||||
lightVibrate,
|
||||
mediumVibrate,
|
||||
heavyVibrate,
|
||||
successVibrate,
|
||||
errorVibrate,
|
||||
warningVibrate,
|
||||
};
|
||||
}
|
||||
@@ -10,7 +10,7 @@ import IssuePeriod from "./issue-period.vue";
|
||||
|
||||
const { t } = useI18n();
|
||||
const now = useNow();
|
||||
const { data: categories } = await safeClient(() => client.api.rwa.issuance.categories.get());
|
||||
const { data: categories, onFetchResponse } = await safeClient(() => client.api.rwa.issuance.categories.get());
|
||||
|
||||
const step = useRouteQuery<number>("step", 1, { transform: v => Number(v), mode: "push" });
|
||||
const initialData: RwaIssuanceProductBody = {
|
||||
@@ -33,6 +33,12 @@ const initialData: RwaIssuanceProductBody = {
|
||||
};
|
||||
const form = useStorage<RwaIssuanceProductBody>("issuing-apply-form", { ...initialData });
|
||||
|
||||
onFetchResponse(() => {
|
||||
if (!form.value.product.categoryId && categories.value?.data && categories.value?.data.length > 0) {
|
||||
form.value.product.categoryId = categories.value?.data![0].id;
|
||||
}
|
||||
});
|
||||
|
||||
function handleNext(values: GenericObject) {
|
||||
form.value.product = { ...values as any };
|
||||
step.value = 2;
|
||||
|
||||
Reference in New Issue
Block a user