@files-preview-app/preview-file 1.3.12 → 1.3.14

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/dist/angular.js CHANGED
@@ -216,6 +216,10 @@ var EXTENSION_MIME_MAP = {
216
216
  ".wav": "audio/wav",
217
217
  ".aac": "audio/aac",
218
218
  ".flac": "audio/flac",
219
+ ".m4a": "audio/mp4",
220
+ ".wma": "audio/x-ms-wma",
221
+ ".opus": "audio/opus",
222
+ ".weba": "audio/webm",
219
223
  // Code/Text
220
224
  ".txt": "text/plain",
221
225
  ".log": "text/plain",
@@ -542,6 +546,7 @@ var ICON_FULLSCREEN = `<svg width="24" height="24" viewBox="0 0 24 24" fill="non
542
546
  var ICON_COPY = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>`;
543
547
  var ICON_FAST_FORWARD = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="13 19 22 12 13 5 13 19"></polygon><polygon points="2 19 11 12 2 5 2 19"></polygon></svg>`;
544
548
  var ICON_REWIND = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="11 19 2 12 11 5 11 19"></polygon><polygon points="22 19 13 12 22 5 22 19"></polygon></svg>`;
549
+ var ICON_SPEED = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg>`;
545
550
  var ICON_EXTERNAL_WINDOW = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"></rect><line x1="3" y1="8" x2="21" y2="8"></line><circle cx="6" cy="5.5" r="0.75" fill="currentColor"></circle><circle cx="8.5" cy="5.5" r="0.75" fill="currentColor"></circle><polyline points="14 13 18 13 18 17"></polyline><line x1="11" y1="20" x2="18" y2="13"></line></svg>`;
546
551
  var ICON_RESET_ZOOM = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line><path d="M13 11a3 3 0 1 0-3 3"></path><path d="M10 11v3h3"></path></svg>`;
547
552
  var ICON_MAP = {
@@ -576,7 +581,8 @@ var ICON_MAP = {
576
581
  "openSeparateWindow": ICON_EXTERNAL_WINDOW,
577
582
  "reset-zoom": ICON_RESET_ZOOM,
578
583
  "zoom-reset": ICON_RESET_ZOOM,
579
- "resetZoom": ICON_RESET_ZOOM
584
+ "resetZoom": ICON_RESET_ZOOM,
585
+ "speed": ICON_SPEED
580
586
  };
581
587
  var ToolbarController = class {
582
588
  el;
@@ -2710,13 +2716,42 @@ var MediaPlugin = class {
2710
2716
  }
2711
2717
  });
2712
2718
  }
2719
+ actions.push({
2720
+ id: "open-window",
2721
+ icon: "open-window",
2722
+ label: "Open in Separate Full Window",
2723
+ type: "button",
2724
+ group: "actions",
2725
+ execute: () => {
2726
+ instance.openInSeparateWindow?.();
2727
+ }
2728
+ });
2713
2729
  return actions;
2714
2730
  }
2715
2731
  async render(ctx) {
2716
- const mimeType = ctx.metadata.mimeType || "application/octet-stream";
2717
- const isImage = mimeType.startsWith("image/") || IMAGE_EXTS.includes(ctx.metadata.extension || "");
2718
- const isVideo = mimeType.startsWith("video/") || VIDEO_EXTS.includes(ctx.metadata.extension || "");
2719
- const isAudio = mimeType.startsWith("audio/") || AUDIO_EXTS.includes(ctx.metadata.extension || "");
2732
+ const ext = (ctx.metadata.extension || "").toLowerCase();
2733
+ let mimeType = ctx.metadata.mimeType || "";
2734
+ if (!mimeType || mimeType === "application/octet-stream") {
2735
+ const audioMimes = {
2736
+ ".mp3": "audio/mpeg",
2737
+ ".wav": "audio/wav",
2738
+ ".ogg": "audio/ogg",
2739
+ ".flac": "audio/flac",
2740
+ ".aac": "audio/aac",
2741
+ ".m4a": "audio/mp4",
2742
+ ".wma": "audio/x-ms-wma",
2743
+ ".opus": "audio/opus",
2744
+ ".weba": "audio/webm"
2745
+ };
2746
+ if (audioMimes[ext]) {
2747
+ mimeType = audioMimes[ext];
2748
+ } else {
2749
+ mimeType = "application/octet-stream";
2750
+ }
2751
+ }
2752
+ const isImage = mimeType.startsWith("image/") || IMAGE_EXTS.includes(ext);
2753
+ const isVideo = mimeType.startsWith("video/") || VIDEO_EXTS.includes(ext);
2754
+ const isAudio = mimeType.startsWith("audio/") || AUDIO_EXTS.includes(ext);
2720
2755
  let url = "";
2721
2756
  let naturalW = 800;
2722
2757
  let naturalH = 600;
@@ -2788,10 +2823,79 @@ var MediaPlugin = class {
2788
2823
  video.addEventListener("canplay", onMeta, { once: true });
2789
2824
  }
2790
2825
  } else if (isAudio) {
2826
+ const audioCard = document.createElement("div");
2827
+ audioCard.className = "fp-audio-card";
2828
+ const artWrapper = document.createElement("div");
2829
+ artWrapper.className = "fp-audio-artwork-wrapper";
2830
+ const disc = document.createElement("div");
2831
+ disc.className = "fp-audio-disc";
2832
+ const discCenter = document.createElement("div");
2833
+ discCenter.className = "fp-audio-disc-center";
2834
+ const discHole = document.createElement("div");
2835
+ discHole.className = "fp-audio-disc-hole";
2836
+ discCenter.appendChild(discHole);
2837
+ disc.appendChild(discCenter);
2838
+ artWrapper.appendChild(disc);
2839
+ audioCard.appendChild(artWrapper);
2840
+ const info = document.createElement("div");
2841
+ info.className = "fp-audio-info";
2842
+ const title = document.createElement("div");
2843
+ title.className = "fp-audio-title";
2844
+ title.textContent = ctx.metadata.name || "Audio Track";
2845
+ const badges = document.createElement("div");
2846
+ badges.className = "fp-audio-badges";
2847
+ const extTag = document.createElement("span");
2848
+ extTag.className = "fp-audio-ext-tag";
2849
+ const cleanExt = (ext || ".mp3").replace(".", "").toUpperCase();
2850
+ extTag.textContent = `${cleanExt} AUDIO`;
2851
+ badges.appendChild(extTag);
2852
+ const timeTag = document.createElement("span");
2853
+ timeTag.className = "fp-audio-time-tag";
2854
+ timeTag.textContent = "0:00";
2855
+ badges.appendChild(timeTag);
2856
+ info.appendChild(title);
2857
+ info.appendChild(badges);
2858
+ audioCard.appendChild(info);
2859
+ const waveform = document.createElement("div");
2860
+ waveform.className = "fp-audio-waveform";
2861
+ for (let i = 0; i < 16; i++) {
2862
+ const bar = document.createElement("div");
2863
+ bar.className = "fp-audio-wave-bar";
2864
+ waveform.appendChild(bar);
2865
+ }
2866
+ audioCard.appendChild(waveform);
2867
+ const nativeWrapper = document.createElement("div");
2868
+ nativeWrapper.className = "fp-audio-native-wrapper";
2791
2869
  const audio = document.createElement("audio");
2792
2870
  audio.src = url;
2793
2871
  audio.controls = true;
2794
- element = audio;
2872
+ nativeWrapper.appendChild(audio);
2873
+ audioCard.appendChild(nativeWrapper);
2874
+ const onPlay = () => {
2875
+ disc.classList.add("playing");
2876
+ waveform.classList.add("playing");
2877
+ };
2878
+ const onPause = () => {
2879
+ disc.classList.remove("playing");
2880
+ waveform.classList.remove("playing");
2881
+ };
2882
+ const formatTime = (secs) => {
2883
+ if (!isFinite(secs) || isNaN(secs)) return "0:00";
2884
+ const m = Math.floor(secs / 60);
2885
+ const s = Math.floor(secs % 60);
2886
+ return `${m}:${s < 10 ? "0" : ""}${s}`;
2887
+ };
2888
+ const onTimeUpdate = () => {
2889
+ timeTag.textContent = `${formatTime(audio.currentTime)} / ${formatTime(audio.duration)}`;
2890
+ };
2891
+ const onLoadedMetadata = () => {
2892
+ timeTag.textContent = `0:00 / ${formatTime(audio.duration)}`;
2893
+ };
2894
+ audio.addEventListener("play", onPlay);
2895
+ audio.addEventListener("pause", onPause);
2896
+ audio.addEventListener("timeupdate", onTimeUpdate);
2897
+ audio.addEventListener("loadedmetadata", onLoadedMetadata);
2898
+ element = audioCard;
2795
2899
  mediaElement = audio;
2796
2900
  } else {
2797
2901
  element = document.createElement("div");
@@ -2801,11 +2905,12 @@ var MediaPlugin = class {
2801
2905
  scrollWrapper.className = "fp-media-scroll-wrapper";
2802
2906
  scrollWrapper.style.minWidth = "100%";
2803
2907
  scrollWrapper.style.minHeight = "100%";
2804
- scrollWrapper.style.width = "max-content";
2805
- scrollWrapper.style.height = "max-content";
2908
+ scrollWrapper.style.width = isAudio ? "100%" : "max-content";
2909
+ scrollWrapper.style.height = isAudio ? "100%" : "max-content";
2806
2910
  scrollWrapper.style.display = "flex";
2807
2911
  scrollWrapper.style.flexDirection = "column";
2808
2912
  scrollWrapper.style.alignItems = "center";
2913
+ scrollWrapper.style.justifyContent = isAudio ? "center" : "flex-start";
2809
2914
  scrollWrapper.style.padding = "16px";
2810
2915
  scrollWrapper.style.boxSizing = "border-box";
2811
2916
  const sizer = document.createElement("div");
@@ -2816,6 +2921,11 @@ var MediaPlugin = class {
2816
2921
  sizer.style.justifyContent = "center";
2817
2922
  sizer.style.alignItems = "center";
2818
2923
  sizer.style.margin = "auto 0";
2924
+ if (isAudio) {
2925
+ sizer.style.width = "100%";
2926
+ sizer.style.maxWidth = "520px";
2927
+ sizer.style.margin = "auto";
2928
+ }
2819
2929
  sizer.appendChild(element);
2820
2930
  scrollWrapper.appendChild(sizer);
2821
2931
  ctx.container.style.overflow = "auto";
@@ -2874,7 +2984,9 @@ var MediaPlugin = class {
2874
2984
  element.style.transformOrigin = "center center";
2875
2985
  element.style.flexShrink = "0";
2876
2986
  } else {
2877
- element.style.transform = `scale(${currentZoom}) rotate(${rotation}deg)`;
2987
+ if (!isAudio) {
2988
+ element.style.transform = `scale(${currentZoom}) rotate(${rotation}deg)`;
2989
+ }
2878
2990
  }
2879
2991
  };
2880
2992
  updateBaseDimensions();
@@ -2900,6 +3012,10 @@ var MediaPlugin = class {
2900
3012
  ro?.observe(ctx.container);
2901
3013
  const cleanup = () => {
2902
3014
  ro?.disconnect();
3015
+ if (mediaElement) {
3016
+ mediaElement.pause();
3017
+ mediaElement.src = "";
3018
+ }
2903
3019
  if (url) URL.revokeObjectURL(url);
2904
3020
  scrollWrapper.remove();
2905
3021
  ctx.container.innerHTML = "";
@@ -2923,36 +3039,54 @@ var MediaPlugin = class {
2923
3039
  currentZoom = level;
2924
3040
  applyTransform();
2925
3041
  } : void 0,
2926
- fitToPage: isImage || isVideo ? () => {
2927
- isUserZoomed = false;
2928
- fitMode = "page";
2929
- currentZoom = 1;
2930
- rotation = 0;
2931
- ctx.container.scrollTop = 0;
2932
- ctx.container.scrollLeft = 0;
2933
- updateBaseDimensions();
2934
- applyTransform();
2935
- } : void 0,
2936
- fitToWidth: isImage || isVideo ? () => {
2937
- isUserZoomed = false;
2938
- fitMode = "width";
2939
- currentZoom = 1;
2940
- rotation = 0;
2941
- ctx.container.scrollTop = 0;
2942
- ctx.container.scrollLeft = 0;
2943
- updateBaseDimensions();
2944
- applyTransform();
2945
- } : void 0,
2946
- resetZoom: isImage || isVideo ? () => {
2947
- isUserZoomed = false;
2948
- fitMode = ctx?.options?.fitMode || "width";
2949
- currentZoom = 1;
2950
- rotation = 0;
2951
- ctx.container.scrollTop = 0;
2952
- ctx.container.scrollLeft = 0;
2953
- updateBaseDimensions();
2954
- applyTransform();
2955
- } : void 0,
3042
+ fitToPage: () => {
3043
+ if (isImage || isVideo) {
3044
+ isUserZoomed = false;
3045
+ fitMode = "page";
3046
+ currentZoom = 1;
3047
+ rotation = 0;
3048
+ ctx.container.scrollTop = 0;
3049
+ ctx.container.scrollLeft = 0;
3050
+ updateBaseDimensions();
3051
+ applyTransform();
3052
+ } else if (isAudio) {
3053
+ ctx.container.scrollTop = 0;
3054
+ ctx.container.scrollLeft = 0;
3055
+ currentZoom = 1;
3056
+ }
3057
+ },
3058
+ fitToWidth: () => {
3059
+ if (isImage || isVideo) {
3060
+ isUserZoomed = false;
3061
+ fitMode = "width";
3062
+ currentZoom = 1;
3063
+ rotation = 0;
3064
+ ctx.container.scrollTop = 0;
3065
+ ctx.container.scrollLeft = 0;
3066
+ updateBaseDimensions();
3067
+ applyTransform();
3068
+ } else if (isAudio) {
3069
+ ctx.container.scrollTop = 0;
3070
+ ctx.container.scrollLeft = 0;
3071
+ currentZoom = 1;
3072
+ }
3073
+ },
3074
+ resetZoom: () => {
3075
+ if (isImage || isVideo) {
3076
+ isUserZoomed = false;
3077
+ fitMode = ctx?.options?.fitMode || "width";
3078
+ currentZoom = 1;
3079
+ rotation = 0;
3080
+ ctx.container.scrollTop = 0;
3081
+ ctx.container.scrollLeft = 0;
3082
+ updateBaseDimensions();
3083
+ applyTransform();
3084
+ } else if (isAudio) {
3085
+ ctx.container.scrollTop = 0;
3086
+ ctx.container.scrollLeft = 0;
3087
+ currentZoom = 1;
3088
+ }
3089
+ },
2956
3090
  rotateCW: isImage || isVideo ? () => {
2957
3091
  rotation = (rotation + 90) % 360;
2958
3092
  applyTransform();