@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/vue.js CHANGED
@@ -168,6 +168,10 @@ var EXTENSION_MIME_MAP = {
168
168
  ".wav": "audio/wav",
169
169
  ".aac": "audio/aac",
170
170
  ".flac": "audio/flac",
171
+ ".m4a": "audio/mp4",
172
+ ".wma": "audio/x-ms-wma",
173
+ ".opus": "audio/opus",
174
+ ".weba": "audio/webm",
171
175
  // Code/Text
172
176
  ".txt": "text/plain",
173
177
  ".log": "text/plain",
@@ -494,6 +498,7 @@ var ICON_FULLSCREEN = `<svg width="24" height="24" viewBox="0 0 24 24" fill="non
494
498
  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>`;
495
499
  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>`;
496
500
  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>`;
501
+ 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>`;
497
502
  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>`;
498
503
  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>`;
499
504
  var ICON_MAP = {
@@ -528,7 +533,8 @@ var ICON_MAP = {
528
533
  "openSeparateWindow": ICON_EXTERNAL_WINDOW,
529
534
  "reset-zoom": ICON_RESET_ZOOM,
530
535
  "zoom-reset": ICON_RESET_ZOOM,
531
- "resetZoom": ICON_RESET_ZOOM
536
+ "resetZoom": ICON_RESET_ZOOM,
537
+ "speed": ICON_SPEED
532
538
  };
533
539
  var ToolbarController = class {
534
540
  el;
@@ -2662,13 +2668,42 @@ var MediaPlugin = class {
2662
2668
  }
2663
2669
  });
2664
2670
  }
2671
+ actions.push({
2672
+ id: "open-window",
2673
+ icon: "open-window",
2674
+ label: "Open in Separate Full Window",
2675
+ type: "button",
2676
+ group: "actions",
2677
+ execute: () => {
2678
+ instance.openInSeparateWindow?.();
2679
+ }
2680
+ });
2665
2681
  return actions;
2666
2682
  }
2667
2683
  async render(ctx) {
2668
- const mimeType = ctx.metadata.mimeType || "application/octet-stream";
2669
- const isImage = mimeType.startsWith("image/") || IMAGE_EXTS.includes(ctx.metadata.extension || "");
2670
- const isVideo = mimeType.startsWith("video/") || VIDEO_EXTS.includes(ctx.metadata.extension || "");
2671
- const isAudio = mimeType.startsWith("audio/") || AUDIO_EXTS.includes(ctx.metadata.extension || "");
2684
+ const ext = (ctx.metadata.extension || "").toLowerCase();
2685
+ let mimeType = ctx.metadata.mimeType || "";
2686
+ if (!mimeType || mimeType === "application/octet-stream") {
2687
+ const audioMimes = {
2688
+ ".mp3": "audio/mpeg",
2689
+ ".wav": "audio/wav",
2690
+ ".ogg": "audio/ogg",
2691
+ ".flac": "audio/flac",
2692
+ ".aac": "audio/aac",
2693
+ ".m4a": "audio/mp4",
2694
+ ".wma": "audio/x-ms-wma",
2695
+ ".opus": "audio/opus",
2696
+ ".weba": "audio/webm"
2697
+ };
2698
+ if (audioMimes[ext]) {
2699
+ mimeType = audioMimes[ext];
2700
+ } else {
2701
+ mimeType = "application/octet-stream";
2702
+ }
2703
+ }
2704
+ const isImage = mimeType.startsWith("image/") || IMAGE_EXTS.includes(ext);
2705
+ const isVideo = mimeType.startsWith("video/") || VIDEO_EXTS.includes(ext);
2706
+ const isAudio = mimeType.startsWith("audio/") || AUDIO_EXTS.includes(ext);
2672
2707
  let url = "";
2673
2708
  let naturalW = 800;
2674
2709
  let naturalH = 600;
@@ -2740,10 +2775,79 @@ var MediaPlugin = class {
2740
2775
  video.addEventListener("canplay", onMeta, { once: true });
2741
2776
  }
2742
2777
  } else if (isAudio) {
2778
+ const audioCard = document.createElement("div");
2779
+ audioCard.className = "fp-audio-card";
2780
+ const artWrapper = document.createElement("div");
2781
+ artWrapper.className = "fp-audio-artwork-wrapper";
2782
+ const disc = document.createElement("div");
2783
+ disc.className = "fp-audio-disc";
2784
+ const discCenter = document.createElement("div");
2785
+ discCenter.className = "fp-audio-disc-center";
2786
+ const discHole = document.createElement("div");
2787
+ discHole.className = "fp-audio-disc-hole";
2788
+ discCenter.appendChild(discHole);
2789
+ disc.appendChild(discCenter);
2790
+ artWrapper.appendChild(disc);
2791
+ audioCard.appendChild(artWrapper);
2792
+ const info = document.createElement("div");
2793
+ info.className = "fp-audio-info";
2794
+ const title = document.createElement("div");
2795
+ title.className = "fp-audio-title";
2796
+ title.textContent = ctx.metadata.name || "Audio Track";
2797
+ const badges = document.createElement("div");
2798
+ badges.className = "fp-audio-badges";
2799
+ const extTag = document.createElement("span");
2800
+ extTag.className = "fp-audio-ext-tag";
2801
+ const cleanExt = (ext || ".mp3").replace(".", "").toUpperCase();
2802
+ extTag.textContent = `${cleanExt} AUDIO`;
2803
+ badges.appendChild(extTag);
2804
+ const timeTag = document.createElement("span");
2805
+ timeTag.className = "fp-audio-time-tag";
2806
+ timeTag.textContent = "0:00";
2807
+ badges.appendChild(timeTag);
2808
+ info.appendChild(title);
2809
+ info.appendChild(badges);
2810
+ audioCard.appendChild(info);
2811
+ const waveform = document.createElement("div");
2812
+ waveform.className = "fp-audio-waveform";
2813
+ for (let i = 0; i < 16; i++) {
2814
+ const bar = document.createElement("div");
2815
+ bar.className = "fp-audio-wave-bar";
2816
+ waveform.appendChild(bar);
2817
+ }
2818
+ audioCard.appendChild(waveform);
2819
+ const nativeWrapper = document.createElement("div");
2820
+ nativeWrapper.className = "fp-audio-native-wrapper";
2743
2821
  const audio = document.createElement("audio");
2744
2822
  audio.src = url;
2745
2823
  audio.controls = true;
2746
- element = audio;
2824
+ nativeWrapper.appendChild(audio);
2825
+ audioCard.appendChild(nativeWrapper);
2826
+ const onPlay = () => {
2827
+ disc.classList.add("playing");
2828
+ waveform.classList.add("playing");
2829
+ };
2830
+ const onPause = () => {
2831
+ disc.classList.remove("playing");
2832
+ waveform.classList.remove("playing");
2833
+ };
2834
+ const formatTime = (secs) => {
2835
+ if (!isFinite(secs) || isNaN(secs)) return "0:00";
2836
+ const m = Math.floor(secs / 60);
2837
+ const s = Math.floor(secs % 60);
2838
+ return `${m}:${s < 10 ? "0" : ""}${s}`;
2839
+ };
2840
+ const onTimeUpdate = () => {
2841
+ timeTag.textContent = `${formatTime(audio.currentTime)} / ${formatTime(audio.duration)}`;
2842
+ };
2843
+ const onLoadedMetadata = () => {
2844
+ timeTag.textContent = `0:00 / ${formatTime(audio.duration)}`;
2845
+ };
2846
+ audio.addEventListener("play", onPlay);
2847
+ audio.addEventListener("pause", onPause);
2848
+ audio.addEventListener("timeupdate", onTimeUpdate);
2849
+ audio.addEventListener("loadedmetadata", onLoadedMetadata);
2850
+ element = audioCard;
2747
2851
  mediaElement = audio;
2748
2852
  } else {
2749
2853
  element = document.createElement("div");
@@ -2753,11 +2857,12 @@ var MediaPlugin = class {
2753
2857
  scrollWrapper.className = "fp-media-scroll-wrapper";
2754
2858
  scrollWrapper.style.minWidth = "100%";
2755
2859
  scrollWrapper.style.minHeight = "100%";
2756
- scrollWrapper.style.width = "max-content";
2757
- scrollWrapper.style.height = "max-content";
2860
+ scrollWrapper.style.width = isAudio ? "100%" : "max-content";
2861
+ scrollWrapper.style.height = isAudio ? "100%" : "max-content";
2758
2862
  scrollWrapper.style.display = "flex";
2759
2863
  scrollWrapper.style.flexDirection = "column";
2760
2864
  scrollWrapper.style.alignItems = "center";
2865
+ scrollWrapper.style.justifyContent = isAudio ? "center" : "flex-start";
2761
2866
  scrollWrapper.style.padding = "16px";
2762
2867
  scrollWrapper.style.boxSizing = "border-box";
2763
2868
  const sizer = document.createElement("div");
@@ -2768,6 +2873,11 @@ var MediaPlugin = class {
2768
2873
  sizer.style.justifyContent = "center";
2769
2874
  sizer.style.alignItems = "center";
2770
2875
  sizer.style.margin = "auto 0";
2876
+ if (isAudio) {
2877
+ sizer.style.width = "100%";
2878
+ sizer.style.maxWidth = "520px";
2879
+ sizer.style.margin = "auto";
2880
+ }
2771
2881
  sizer.appendChild(element);
2772
2882
  scrollWrapper.appendChild(sizer);
2773
2883
  ctx.container.style.overflow = "auto";
@@ -2826,7 +2936,9 @@ var MediaPlugin = class {
2826
2936
  element.style.transformOrigin = "center center";
2827
2937
  element.style.flexShrink = "0";
2828
2938
  } else {
2829
- element.style.transform = `scale(${currentZoom}) rotate(${rotation}deg)`;
2939
+ if (!isAudio) {
2940
+ element.style.transform = `scale(${currentZoom}) rotate(${rotation}deg)`;
2941
+ }
2830
2942
  }
2831
2943
  };
2832
2944
  updateBaseDimensions();
@@ -2852,6 +2964,10 @@ var MediaPlugin = class {
2852
2964
  ro?.observe(ctx.container);
2853
2965
  const cleanup = () => {
2854
2966
  ro?.disconnect();
2967
+ if (mediaElement) {
2968
+ mediaElement.pause();
2969
+ mediaElement.src = "";
2970
+ }
2855
2971
  if (url) URL.revokeObjectURL(url);
2856
2972
  scrollWrapper.remove();
2857
2973
  ctx.container.innerHTML = "";
@@ -2875,36 +2991,54 @@ var MediaPlugin = class {
2875
2991
  currentZoom = level;
2876
2992
  applyTransform();
2877
2993
  } : void 0,
2878
- fitToPage: isImage || isVideo ? () => {
2879
- isUserZoomed = false;
2880
- fitMode = "page";
2881
- currentZoom = 1;
2882
- rotation = 0;
2883
- ctx.container.scrollTop = 0;
2884
- ctx.container.scrollLeft = 0;
2885
- updateBaseDimensions();
2886
- applyTransform();
2887
- } : void 0,
2888
- fitToWidth: isImage || isVideo ? () => {
2889
- isUserZoomed = false;
2890
- fitMode = "width";
2891
- currentZoom = 1;
2892
- rotation = 0;
2893
- ctx.container.scrollTop = 0;
2894
- ctx.container.scrollLeft = 0;
2895
- updateBaseDimensions();
2896
- applyTransform();
2897
- } : void 0,
2898
- resetZoom: isImage || isVideo ? () => {
2899
- isUserZoomed = false;
2900
- fitMode = ctx?.options?.fitMode || "width";
2901
- currentZoom = 1;
2902
- rotation = 0;
2903
- ctx.container.scrollTop = 0;
2904
- ctx.container.scrollLeft = 0;
2905
- updateBaseDimensions();
2906
- applyTransform();
2907
- } : void 0,
2994
+ fitToPage: () => {
2995
+ if (isImage || isVideo) {
2996
+ isUserZoomed = false;
2997
+ fitMode = "page";
2998
+ currentZoom = 1;
2999
+ rotation = 0;
3000
+ ctx.container.scrollTop = 0;
3001
+ ctx.container.scrollLeft = 0;
3002
+ updateBaseDimensions();
3003
+ applyTransform();
3004
+ } else if (isAudio) {
3005
+ ctx.container.scrollTop = 0;
3006
+ ctx.container.scrollLeft = 0;
3007
+ currentZoom = 1;
3008
+ }
3009
+ },
3010
+ fitToWidth: () => {
3011
+ if (isImage || isVideo) {
3012
+ isUserZoomed = false;
3013
+ fitMode = "width";
3014
+ currentZoom = 1;
3015
+ rotation = 0;
3016
+ ctx.container.scrollTop = 0;
3017
+ ctx.container.scrollLeft = 0;
3018
+ updateBaseDimensions();
3019
+ applyTransform();
3020
+ } else if (isAudio) {
3021
+ ctx.container.scrollTop = 0;
3022
+ ctx.container.scrollLeft = 0;
3023
+ currentZoom = 1;
3024
+ }
3025
+ },
3026
+ resetZoom: () => {
3027
+ if (isImage || isVideo) {
3028
+ isUserZoomed = false;
3029
+ fitMode = ctx?.options?.fitMode || "width";
3030
+ currentZoom = 1;
3031
+ rotation = 0;
3032
+ ctx.container.scrollTop = 0;
3033
+ ctx.container.scrollLeft = 0;
3034
+ updateBaseDimensions();
3035
+ applyTransform();
3036
+ } else if (isAudio) {
3037
+ ctx.container.scrollTop = 0;
3038
+ ctx.container.scrollLeft = 0;
3039
+ currentZoom = 1;
3040
+ }
3041
+ },
2908
3042
  rotateCW: isImage || isVideo ? () => {
2909
3043
  rotation = (rotation + 90) % 360;
2910
3044
  applyTransform();