ssovee-os-web-ui 0.1.36 → 0.1.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -75,7 +75,7 @@ const app = {
75
75
 
76
76
  export function NotesWindow() {
77
77
  return (
78
- <WindowWithoutSideMenu app={app} defaultSize={{ width: 420, height: 320 }}>
78
+ <WindowWithoutSideMenu app={app} defaultSize={ { width: 420, height: 320 } }>
79
79
  <Typography variant="h6">Notes</Typography>
80
80
  </WindowWithoutSideMenu>
81
81
  );
@@ -102,15 +102,15 @@ export function SettingsWindow() {
102
102
  return (
103
103
  <WindowWithSideMenu
104
104
  app={app}
105
- defaultSize={{ width: 720, height: 500 }}
106
- actionButtons={{ title: "Save", onClick: () => console.log("Saved") }}
107
- menu={{
105
+ defaultSize={ { width: 720, height: 500 } }
106
+ actionButtons={ { title: "Save", onClick: () => console.log("Saved") } }
107
+ menu={ {
108
108
  title: "Navigation",
109
109
  items: [
110
110
  { title: "Profile", icon: "👤", onClick: () => console.log("Profile"), isActive: true },
111
111
  { title: "Security", icon: "🔒", onClick: () => console.log("Security") },
112
112
  ],
113
- }}
113
+ } }
114
114
  >
115
115
  <Typography variant="h6">Settings</Typography>
116
116
  <Button variant="primary">Update</Button>
@@ -126,7 +126,7 @@ import { Skeleton } from "ssovee-os-web-ui";
126
126
 
127
127
  export function LoadingState() {
128
128
  return (
129
- <div style={{ display: "grid", gap: 12 }}>
129
+ <div style={ { display: "grid", gap: 12 } }>
130
130
  <Skeleton variant="text" lines={3} />
131
131
  <Skeleton variant="avatar" className="h-12 w-12" />
132
132
  <Skeleton variant="image" className="h-40" />
package/dist/index.cjs CHANGED
@@ -3265,6 +3265,14 @@ var soundMap = {
3265
3265
  success: success_tone_default,
3266
3266
  swipe: swipe_tone_default
3267
3267
  };
3268
+ var fallbackToneMap = {
3269
+ click: { frequency: 900, durationMs: 70 },
3270
+ swipe: { frequency: 740, durationMs: 90 },
3271
+ success: { frequency: 660, durationMs: 140 },
3272
+ notification: { frequency: 580, durationMs: 130 },
3273
+ error: { frequency: 260, durationMs: 180 },
3274
+ alert: { frequency: 300, durationMs: 170 }
3275
+ };
3268
3276
  var pendingPlaybackQueue = [];
3269
3277
  var interactionListenersBound = false;
3270
3278
  var clampVolume = (value) => Math.min(1, Math.max(0, value));
@@ -3294,6 +3302,35 @@ var isAutoplayRestrictionError = (error) => {
3294
3302
  const message = maybeError.message?.toLowerCase() ?? "";
3295
3303
  return maybeError.name === "NotAllowedError" || message.includes("gesture") || message.includes("user");
3296
3304
  };
3305
+ var playFallbackTone = (type, volume) => {
3306
+ if (typeof window === "undefined") return false;
3307
+ const Ctx = window.AudioContext || window.webkitAudioContext;
3308
+ if (!Ctx) return false;
3309
+ try {
3310
+ const context = new Ctx();
3311
+ const oscillator = context.createOscillator();
3312
+ const gain = context.createGain();
3313
+ const { frequency, durationMs } = fallbackToneMap[type];
3314
+ oscillator.type = type === "error" || type === "alert" ? "square" : "sine";
3315
+ oscillator.frequency.value = frequency;
3316
+ const now = context.currentTime;
3317
+ const end = now + durationMs / 1e3;
3318
+ const safeVolume = Math.min(0.12, Math.max(0.01, volume * 0.08));
3319
+ gain.gain.setValueAtTime(1e-4, now);
3320
+ gain.gain.exponentialRampToValueAtTime(safeVolume, now + 0.01);
3321
+ gain.gain.exponentialRampToValueAtTime(1e-4, end);
3322
+ oscillator.connect(gain);
3323
+ gain.connect(context.destination);
3324
+ oscillator.start(now);
3325
+ oscillator.stop(end);
3326
+ oscillator.onended = () => {
3327
+ void context.close();
3328
+ };
3329
+ return true;
3330
+ } catch {
3331
+ return false;
3332
+ }
3333
+ };
3297
3334
  var playNativeAudio = async (type, options) => {
3298
3335
  if (typeof window === "undefined" || typeof window.Audio === "undefined") {
3299
3336
  return false;
@@ -3309,10 +3346,14 @@ var playNativeAudio = async (type, options) => {
3309
3346
  await audio.play();
3310
3347
  return true;
3311
3348
  } catch (err) {
3312
- if (!isAutoplayRestrictionError(err)) {
3349
+ if (isAutoplayRestrictionError(err)) {
3350
+ return false;
3351
+ }
3352
+ const fallbackPlayed = playFallbackTone(type, clampVolume(options?.volume ?? 1));
3353
+ if (!fallbackPlayed) {
3313
3354
  console.error("Sound playback failed:", err);
3314
3355
  }
3315
- return false;
3356
+ return fallbackPlayed;
3316
3357
  }
3317
3358
  };
3318
3359
  var flushPendingQueue = () => {