napp-wallet-post-feed-test 1.0.47
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 +157 -0
- package/dist/0ae4e6254fc19607c79e.woff2 +0 -0
- package/dist/1f38a564cd9eae27ebc3.woff2 +0 -0
- package/dist/432.napp.bundle.js +1 -0
- package/dist/661bd6b7245d5205d3e1.woff2 +0 -0
- package/dist/Post.browser.js +24 -0
- package/dist/Post.js +606 -0
- package/dist/components/CodeSplitting.js +88 -0
- package/dist/components/Deeplink/Deeplink.js +813 -0
- package/dist/components/EditPostModal.js +916 -0
- package/dist/components/ErrorBoundary.js +74 -0
- package/dist/components/ExpandedTest/ExpandableText.js +38 -0
- package/dist/components/FilterDropdown.js +71 -0
- package/dist/components/ImagePreloader.js +1194 -0
- package/dist/components/Loader.js +42 -0
- package/dist/components/LoadingSkeletons.js +978 -0
- package/dist/components/MediaRenderer.js +759 -0
- package/dist/components/MemoryManager.js +302 -0
- package/dist/components/PostCard.js +446 -0
- package/dist/components/PostViews.js +247 -0
- package/dist/components/Postfeed.js +251 -0
- package/dist/components/Svgloader.js +231 -0
- package/dist/components/UploadPostModal.js +1352 -0
- package/dist/components/VideoPlayer.js +1304 -0
- package/dist/components/ViewPostModal/MediaPreloadManager.js +379 -0
- package/dist/components/ViewPostModal/README.md +164 -0
- package/dist/components/ViewPostModal/ShareModal.js +96 -0
- package/dist/components/ViewPostModal/VirtualPost.js +248 -0
- package/dist/components/ViewPostModal/useBodyScrollLock.js +42 -0
- package/dist/components/ViewPostModal/useDeviceDetection.js +38 -0
- package/dist/components/ViewPostModal/useFullscreenManager.js +43 -0
- package/dist/components/ViewPostModal/useNavigationManager.js +185 -0
- package/dist/components/ViewPostModal/usePostDataManager.js +143 -0
- package/dist/components/ViewPostModal/usePreloadManager.js +97 -0
- package/dist/components/ViewPostModal/useShareManager.js +76 -0
- package/dist/components/ViewPostModal.js +552 -0
- package/dist/components/VirtualPostFeed.js +475 -0
- package/dist/components/hooks/useFeedVisibility.js +72 -0
- package/dist/components/hooks/useIntersectionObserver.js +54 -0
- package/dist/components/hooks/usePerformanceMonitor.js +159 -0
- package/dist/components/hooks/usePostApi.js +381 -0
- package/dist/components/hooks/usePostState.js +116 -0
- package/dist/components/useImagePreloading.js +231 -0
- package/dist/e7461d69dbbff1310a5c.woff2 +0 -0
- package/dist/helper/Helper.js +504 -0
- package/dist/index.browser.js +5 -0
- package/dist/index.js +3 -0
- package/dist/napp.bundle.js +2 -0
- package/dist/napp.bundle.js.LICENSE.txt +733 -0
- package/dist/style/post.css +5751 -0
- package/dist/style/post.css.map +1 -0
- package/dist/style/post.purged.css +3236 -0
- package/dist/style/post.scss +5910 -0
- package/dist/utils/bootstrap.js +4 -0
- package/dist/utils/ffmpegLoader.js +40 -0
- package/package.json +70 -0
|
@@ -0,0 +1,916 @@
|
|
|
1
|
+
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
|
|
2
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
3
|
+
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
|
|
4
|
+
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
|
|
5
|
+
function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i.return) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
|
|
6
|
+
function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { if (r) i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n;else { var o = function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); }; o("next", 0), o("throw", 1), o("return", 2); } }, _regeneratorDefine2(e, r, n, t); }
|
|
7
|
+
function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
|
|
8
|
+
function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
|
|
9
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
10
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
11
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
12
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
13
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
14
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
15
|
+
import React from "react";
|
|
16
|
+
import useState from "react";
|
|
17
|
+
import useEffect from "react";
|
|
18
|
+
import useRef from "react";
|
|
19
|
+
import useCallback from "react";
|
|
20
|
+
import { Modal, Button, Form, Container, FloatingLabel } from "react-bootstrap";
|
|
21
|
+
import { UploadIcon, TrashIcon, EditIcon } from "./Svgloader";
|
|
22
|
+
// import { editPostApi } from "../helper/Helper"; // Commented out - edit functionality not needed
|
|
23
|
+
import VideoPlayer from "./VideoPlayer";
|
|
24
|
+
import $ from "jquery";
|
|
25
|
+
import { toast } from 'react-toastify';
|
|
26
|
+
import { memoryManager } from "./MemoryManager";
|
|
27
|
+
import { loadFFmpeg, isFFmpegAvailable } from "../utils/ffmpegLoader";
|
|
28
|
+
import { triggerImageCacheBust } from "./MediaRenderer";
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* EditPostModal - Enhanced Post Editing Component
|
|
32
|
+
*
|
|
33
|
+
* Features:
|
|
34
|
+
* - Edit text content (title and description)
|
|
35
|
+
* - Replace existing media files only (no adding new media)
|
|
36
|
+
* - Automatic image compression to WebP format
|
|
37
|
+
* - FFmpeg-based video compression with MediaRecorder fallback
|
|
38
|
+
* - Seamless file replacement workflow
|
|
39
|
+
* - Memory management and cleanup
|
|
40
|
+
*
|
|
41
|
+
* Restrictions:
|
|
42
|
+
* - Cannot add new media files in edit mode
|
|
43
|
+
* - Can only replace existing media
|
|
44
|
+
* - If no media exists, only text editing is available
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
// Media compression constants
|
|
48
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
49
|
+
var IMAGE_QUALITY = 0.8; // Higher quality for WebP
|
|
50
|
+
var VIDEO_MAX_SIZE = 25 * 1024 * 1024; // 25 MB
|
|
51
|
+
var VIDEO_TARGET_SIZE = 15 * 1024 * 1024; // 15 MB target
|
|
52
|
+
var VIDEO_MAX_WIDTH = 1280;
|
|
53
|
+
var VIDEO_MAX_HEIGHT = 720;
|
|
54
|
+
var EditPostModal = function EditPostModal(_ref) {
|
|
55
|
+
var show = _ref.show,
|
|
56
|
+
handleClose = _ref.handleClose,
|
|
57
|
+
postData = _ref.postData,
|
|
58
|
+
refreshData = _ref.refreshData;
|
|
59
|
+
var _useState = useState(""),
|
|
60
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
61
|
+
postTitle = _useState2[0],
|
|
62
|
+
setPostTitle = _useState2[1];
|
|
63
|
+
var _useState3 = useState(""),
|
|
64
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
65
|
+
postContent = _useState4[0],
|
|
66
|
+
setPostContent = _useState4[1];
|
|
67
|
+
var _useState5 = useState([]),
|
|
68
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
69
|
+
previews = _useState6[0],
|
|
70
|
+
setPreviews = _useState6[1]; // Already saved files
|
|
71
|
+
var _useState7 = useState([]),
|
|
72
|
+
_useState8 = _slicedToArray(_useState7, 2),
|
|
73
|
+
replacementFiles = _useState8[0],
|
|
74
|
+
setReplacementFiles = _useState8[1]; // Files to replace existing media
|
|
75
|
+
var _useState9 = useState([]),
|
|
76
|
+
_useState0 = _slicedToArray(_useState9, 2),
|
|
77
|
+
deletedEditedPost = _useState0[0],
|
|
78
|
+
setDeletedEditedPost = _useState0[1]; // Initialize state for deleted files
|
|
79
|
+
var singleEditInputFileChooserRef = useRef(null);
|
|
80
|
+
var _useState1 = useState(false),
|
|
81
|
+
_useState10 = _slicedToArray(_useState1, 2),
|
|
82
|
+
updateMainthumbnail = _useState10[0],
|
|
83
|
+
setUpdateMainthumbnail = _useState10[1];
|
|
84
|
+
var _useState11 = useState(false),
|
|
85
|
+
_useState12 = _slicedToArray(_useState11, 2),
|
|
86
|
+
isProcessing = _useState12[0],
|
|
87
|
+
setIsProcessing = _useState12[1];
|
|
88
|
+
var _useState13 = useState(0),
|
|
89
|
+
_useState14 = _slicedToArray(_useState13, 2),
|
|
90
|
+
processingProgress = _useState14[0],
|
|
91
|
+
setProcessingProgress = _useState14[1];
|
|
92
|
+
var _useState15 = useState(""),
|
|
93
|
+
_useState16 = _slicedToArray(_useState15, 2),
|
|
94
|
+
processingDetails = _useState16[0],
|
|
95
|
+
setProcessingDetails = _useState16[1];
|
|
96
|
+
var _useState17 = useState(""),
|
|
97
|
+
_useState18 = _slicedToArray(_useState17, 2),
|
|
98
|
+
errorMessage = _useState18[0],
|
|
99
|
+
setErrorMessage = _useState18[1];
|
|
100
|
+
var _useState19 = useState(0),
|
|
101
|
+
_useState20 = _slicedToArray(_useState19, 2),
|
|
102
|
+
updateCounter = _useState20[0],
|
|
103
|
+
setUpdateCounter = _useState20[1];
|
|
104
|
+
|
|
105
|
+
// WebP conversion for images
|
|
106
|
+
var convertToWebP = useCallback(/*#__PURE__*/function () {
|
|
107
|
+
var _ref2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(file, progressCallback) {
|
|
108
|
+
return _regenerator().w(function (_context2) {
|
|
109
|
+
while (1) switch (_context2.n) {
|
|
110
|
+
case 0:
|
|
111
|
+
return _context2.a(2, new Promise(function (resolve) {
|
|
112
|
+
var img = new window.Image();
|
|
113
|
+
img.onload = /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
|
|
114
|
+
var canvas, ctx, width, height, maxWidth, maxHeight, ratio;
|
|
115
|
+
return _regenerator().w(function (_context) {
|
|
116
|
+
while (1) switch (_context.n) {
|
|
117
|
+
case 0:
|
|
118
|
+
progressCallback === null || progressCallback === void 0 || progressCallback(10, "Converting to WebP...");
|
|
119
|
+
canvas = document.createElement('canvas');
|
|
120
|
+
ctx = canvas.getContext('2d'); // Maintain aspect ratio but limit size
|
|
121
|
+
width = img.width, height = img.height;
|
|
122
|
+
maxWidth = 1920;
|
|
123
|
+
maxHeight = 1080;
|
|
124
|
+
if (width > maxWidth || height > maxHeight) {
|
|
125
|
+
ratio = Math.min(maxWidth / width, maxHeight / height);
|
|
126
|
+
width = Math.round(width * ratio);
|
|
127
|
+
height = Math.round(height * ratio);
|
|
128
|
+
}
|
|
129
|
+
canvas.width = width;
|
|
130
|
+
canvas.height = height;
|
|
131
|
+
progressCallback === null || progressCallback === void 0 || progressCallback(50, "Processing image...");
|
|
132
|
+
ctx.imageSmoothingEnabled = true;
|
|
133
|
+
ctx.imageSmoothingQuality = 'high';
|
|
134
|
+
ctx.drawImage(img, 0, 0, width, height);
|
|
135
|
+
progressCallback === null || progressCallback === void 0 || progressCallback(80, "Finalizing WebP...");
|
|
136
|
+
canvas.toBlob(function (blob) {
|
|
137
|
+
var webpFile = new File([blob], file.name.replace(/\.[^/.]+$/, ".webp"), {
|
|
138
|
+
type: "image/webp",
|
|
139
|
+
lastModified: Date.now()
|
|
140
|
+
});
|
|
141
|
+
progressCallback === null || progressCallback === void 0 || progressCallback(100, "WebP conversion complete!");
|
|
142
|
+
resolve(webpFile);
|
|
143
|
+
}, "image/webp", IMAGE_QUALITY);
|
|
144
|
+
case 1:
|
|
145
|
+
return _context.a(2);
|
|
146
|
+
}
|
|
147
|
+
}, _callee);
|
|
148
|
+
}));
|
|
149
|
+
img.onerror = function () {
|
|
150
|
+
progressCallback === null || progressCallback === void 0 || progressCallback(100, "WebP conversion failed, using original");
|
|
151
|
+
resolve(file);
|
|
152
|
+
};
|
|
153
|
+
img.src = URL.createObjectURL(file);
|
|
154
|
+
}));
|
|
155
|
+
}
|
|
156
|
+
}, _callee2);
|
|
157
|
+
}));
|
|
158
|
+
return function (_x, _x2) {
|
|
159
|
+
return _ref2.apply(this, arguments);
|
|
160
|
+
};
|
|
161
|
+
}(), []);
|
|
162
|
+
|
|
163
|
+
// Enhanced video compression with multiple fallback strategies
|
|
164
|
+
var compressVideoWithFFmpeg = useCallback(/*#__PURE__*/function () {
|
|
165
|
+
var _ref4 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5(file, progressCallback) {
|
|
166
|
+
return _regenerator().w(function (_context5) {
|
|
167
|
+
while (1) switch (_context5.n) {
|
|
168
|
+
case 0:
|
|
169
|
+
return _context5.a(2, new Promise(/*#__PURE__*/function () {
|
|
170
|
+
var _ref5 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4(resolve) {
|
|
171
|
+
var ffmpeg, inputName, outputName, data, compressedBlob, compressedFile, video, canvas, ctx, _t2, _t3, _t4, _t5, _t6;
|
|
172
|
+
return _regenerator().w(function (_context4) {
|
|
173
|
+
while (1) switch (_context4.n) {
|
|
174
|
+
case 0:
|
|
175
|
+
_context4.p = 0;
|
|
176
|
+
// First, try FFmpeg compression
|
|
177
|
+
progressCallback === null || progressCallback === void 0 || progressCallback(10, "Loading FFmpeg...");
|
|
178
|
+
_context4.n = 1;
|
|
179
|
+
return loadFFmpeg();
|
|
180
|
+
case 1:
|
|
181
|
+
ffmpeg = _context4.v;
|
|
182
|
+
if (!(ffmpeg && isFFmpegAvailable())) {
|
|
183
|
+
_context4.n = 10;
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
_context4.p = 2;
|
|
187
|
+
progressCallback === null || progressCallback === void 0 || progressCallback(20, "Processing video with FFmpeg...");
|
|
188
|
+
inputName = "input.".concat(file.name.split('.').pop());
|
|
189
|
+
outputName = "output.webm"; // Write input file to FFmpeg
|
|
190
|
+
_t2 = ffmpeg;
|
|
191
|
+
_t3 = inputName;
|
|
192
|
+
_context4.n = 3;
|
|
193
|
+
return file.arrayBuffer();
|
|
194
|
+
case 3:
|
|
195
|
+
_t4 = _context4.v;
|
|
196
|
+
_context4.n = 4;
|
|
197
|
+
return _t2.writeFile.call(_t2, _t3, _t4);
|
|
198
|
+
case 4:
|
|
199
|
+
progressCallback === null || progressCallback === void 0 || progressCallback(40, "Compressing video...");
|
|
200
|
+
|
|
201
|
+
// FFmpeg command for compression
|
|
202
|
+
_context4.n = 5;
|
|
203
|
+
return ffmpeg.exec(['-i', inputName, '-c:v', 'libvpx-vp9', '-crf', '30', '-b:v', '1M', '-maxrate', '1.5M', '-bufsize', '2M', '-vf', "scale=".concat(VIDEO_MAX_WIDTH, ":").concat(VIDEO_MAX_HEIGHT, ":force_original_aspect_ratio=decrease"), '-c:a', 'libopus', '-b:a', '128k', '-f', 'webm', outputName]);
|
|
204
|
+
case 5:
|
|
205
|
+
progressCallback === null || progressCallback === void 0 || progressCallback(80, "Finalizing compressed video...");
|
|
206
|
+
|
|
207
|
+
// Read the output file
|
|
208
|
+
_context4.n = 6;
|
|
209
|
+
return ffmpeg.readFile(outputName);
|
|
210
|
+
case 6:
|
|
211
|
+
data = _context4.v;
|
|
212
|
+
compressedBlob = new Blob([data.buffer], {
|
|
213
|
+
type: 'video/webm'
|
|
214
|
+
}); // Clean up
|
|
215
|
+
_context4.n = 7;
|
|
216
|
+
return ffmpeg.deleteFile(inputName);
|
|
217
|
+
case 7:
|
|
218
|
+
_context4.n = 8;
|
|
219
|
+
return ffmpeg.deleteFile(outputName);
|
|
220
|
+
case 8:
|
|
221
|
+
compressedFile = new File([compressedBlob], file.name.replace(/\.[^/.]+$/, ".webm"), {
|
|
222
|
+
type: "video/webm",
|
|
223
|
+
lastModified: Date.now()
|
|
224
|
+
});
|
|
225
|
+
progressCallback === null || progressCallback === void 0 || progressCallback(100, "Video compressed to ".concat((compressedBlob.size / (1024 * 1024)).toFixed(2), " MB"));
|
|
226
|
+
resolve(compressedFile);
|
|
227
|
+
return _context4.a(2);
|
|
228
|
+
case 9:
|
|
229
|
+
_context4.p = 9;
|
|
230
|
+
_t5 = _context4.v;
|
|
231
|
+
case 10:
|
|
232
|
+
// Fallback: Use MediaRecorder for basic compression
|
|
233
|
+
progressCallback === null || progressCallback === void 0 || progressCallback(50, "Using fallback compression...");
|
|
234
|
+
if (window.MediaRecorder) {
|
|
235
|
+
_context4.n = 11;
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
progressCallback === null || progressCallback === void 0 || progressCallback(100, "No compression available, using original");
|
|
239
|
+
resolve(file);
|
|
240
|
+
return _context4.a(2);
|
|
241
|
+
case 11:
|
|
242
|
+
video = document.createElement('video');
|
|
243
|
+
canvas = document.createElement('canvas');
|
|
244
|
+
ctx = canvas.getContext('2d');
|
|
245
|
+
video.onerror = function () {
|
|
246
|
+
progressCallback === null || progressCallback === void 0 || progressCallback(100, "Video processing failed, using original");
|
|
247
|
+
resolve(file);
|
|
248
|
+
};
|
|
249
|
+
video.onloadedmetadata = /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3() {
|
|
250
|
+
var width, height, maxWidth, maxHeight, ratio, stream, mimeType, mediaRecorder, chunks, _captureFrame, duration, _t;
|
|
251
|
+
return _regenerator().w(function (_context3) {
|
|
252
|
+
while (1) switch (_context3.n) {
|
|
253
|
+
case 0:
|
|
254
|
+
_context3.p = 0;
|
|
255
|
+
progressCallback === null || progressCallback === void 0 || progressCallback(70, "Setting up fallback compression...");
|
|
256
|
+
width = video.width, height = video.height;
|
|
257
|
+
maxWidth = VIDEO_MAX_WIDTH;
|
|
258
|
+
maxHeight = VIDEO_MAX_HEIGHT;
|
|
259
|
+
if (width > maxWidth || height > maxHeight) {
|
|
260
|
+
ratio = Math.min(maxWidth / width, maxHeight / height);
|
|
261
|
+
width = Math.round(width * ratio);
|
|
262
|
+
height = Math.round(height * ratio);
|
|
263
|
+
}
|
|
264
|
+
canvas.width = width;
|
|
265
|
+
canvas.height = height;
|
|
266
|
+
stream = canvas.captureStream(30);
|
|
267
|
+
mimeType = 'video/webm;codecs=vp8';
|
|
268
|
+
if (MediaRecorder.isTypeSupported(mimeType)) {
|
|
269
|
+
_context3.n = 1;
|
|
270
|
+
break;
|
|
271
|
+
}
|
|
272
|
+
progressCallback === null || progressCallback === void 0 || progressCallback(100, "WebM not supported, using original");
|
|
273
|
+
resolve(file);
|
|
274
|
+
return _context3.a(2);
|
|
275
|
+
case 1:
|
|
276
|
+
mediaRecorder = new MediaRecorder(stream, {
|
|
277
|
+
mimeType: mimeType,
|
|
278
|
+
videoBitsPerSecond: 1000000 // 1 Mbps
|
|
279
|
+
});
|
|
280
|
+
chunks = [];
|
|
281
|
+
mediaRecorder.ondataavailable = function (event) {
|
|
282
|
+
if (event.data.size > 0) {
|
|
283
|
+
chunks.push(event.data);
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
mediaRecorder.onstop = function () {
|
|
287
|
+
var compressedBlob = new Blob(chunks, {
|
|
288
|
+
type: mimeType
|
|
289
|
+
});
|
|
290
|
+
var compressedFile = new File([compressedBlob], file.name.replace(/\.[^/.]+$/, ".webm"), {
|
|
291
|
+
type: mimeType,
|
|
292
|
+
lastModified: Date.now()
|
|
293
|
+
});
|
|
294
|
+
progressCallback === null || progressCallback === void 0 || progressCallback(100, "Video compressed to ".concat((compressedBlob.size / (1024 * 1024)).toFixed(2), " MB"));
|
|
295
|
+
resolve(compressedFile);
|
|
296
|
+
};
|
|
297
|
+
mediaRecorder.start();
|
|
298
|
+
|
|
299
|
+
// Play video and capture frames
|
|
300
|
+
video.currentTime = 0;
|
|
301
|
+
video.play();
|
|
302
|
+
_captureFrame = function captureFrame() {
|
|
303
|
+
if (video.ended || video.paused) {
|
|
304
|
+
mediaRecorder.stop();
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
ctx.drawImage(video, 0, 0, width, height);
|
|
308
|
+
requestAnimationFrame(_captureFrame);
|
|
309
|
+
};
|
|
310
|
+
video.onplay = function () {
|
|
311
|
+
_captureFrame();
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
// Record for the duration of the video or max 30 seconds
|
|
315
|
+
duration = Math.min(video.duration || 30, 30);
|
|
316
|
+
setTimeout(function () {
|
|
317
|
+
if (mediaRecorder.state === 'recording') {
|
|
318
|
+
mediaRecorder.stop();
|
|
319
|
+
}
|
|
320
|
+
}, duration * 1000);
|
|
321
|
+
_context3.n = 3;
|
|
322
|
+
break;
|
|
323
|
+
case 2:
|
|
324
|
+
_context3.p = 2;
|
|
325
|
+
_t = _context3.v;
|
|
326
|
+
// Fallback compression failed
|
|
327
|
+
progressCallback === null || progressCallback === void 0 || progressCallback(100, "All compression methods failed, using original");
|
|
328
|
+
resolve(file);
|
|
329
|
+
case 3:
|
|
330
|
+
return _context3.a(2);
|
|
331
|
+
}
|
|
332
|
+
}, _callee3, null, [[0, 2]]);
|
|
333
|
+
}));
|
|
334
|
+
video.src = URL.createObjectURL(file);
|
|
335
|
+
_context4.n = 13;
|
|
336
|
+
break;
|
|
337
|
+
case 12:
|
|
338
|
+
_context4.p = 12;
|
|
339
|
+
_t6 = _context4.v;
|
|
340
|
+
// Video compression failed
|
|
341
|
+
progressCallback === null || progressCallback === void 0 || progressCallback(100, "Video compression failed, using original");
|
|
342
|
+
resolve(file);
|
|
343
|
+
case 13:
|
|
344
|
+
return _context4.a(2);
|
|
345
|
+
}
|
|
346
|
+
}, _callee4, null, [[2, 9], [0, 12]]);
|
|
347
|
+
}));
|
|
348
|
+
return function (_x5) {
|
|
349
|
+
return _ref5.apply(this, arguments);
|
|
350
|
+
};
|
|
351
|
+
}()));
|
|
352
|
+
}
|
|
353
|
+
}, _callee5);
|
|
354
|
+
}));
|
|
355
|
+
return function (_x3, _x4) {
|
|
356
|
+
return _ref4.apply(this, arguments);
|
|
357
|
+
};
|
|
358
|
+
}(), []);
|
|
359
|
+
|
|
360
|
+
// Set up data attributes when postData changes
|
|
361
|
+
useEffect(function () {
|
|
362
|
+
if (postData) {
|
|
363
|
+
$("#post-edit-btn").attr("data-orig-id", postData.originalAuxID);
|
|
364
|
+
$("#post-edit-btn").attr("data-ff-name", postData.postFileFriendlyName);
|
|
365
|
+
$("#post-edit-btn").attr("data-parent-rsm", postData.rsmguid);
|
|
366
|
+
$("#post-edit-btn").attr("data-no-media", postData.postImage == "" ? true : false);
|
|
367
|
+
$("#item-carousel-data").attr("data-file-friendlyname", postData.postFileFriendlyName);
|
|
368
|
+
}
|
|
369
|
+
}, [postData]);
|
|
370
|
+
|
|
371
|
+
// Reset state and set post data when modal is opened or postData changes
|
|
372
|
+
useEffect(function () {
|
|
373
|
+
if (show && postData) {
|
|
374
|
+
setPostTitle(postData.postOnPageTitle || "");
|
|
375
|
+
setPostContent(postData.postOnPageExpandedText || "");
|
|
376
|
+
setPreviews([]);
|
|
377
|
+
setReplacementFiles([]);
|
|
378
|
+
setErrorMessage("");
|
|
379
|
+
setIsProcessing(false);
|
|
380
|
+
setProcessingProgress(0);
|
|
381
|
+
setProcessingDetails("");
|
|
382
|
+
var previewsArray = [];
|
|
383
|
+
|
|
384
|
+
// Main Post Media
|
|
385
|
+
if (postData.postImage) {
|
|
386
|
+
var url = postData.postImage;
|
|
387
|
+
var isVideo = isVideoFile(url, postData.fileMediaTypeRR);
|
|
388
|
+
previewsArray.push({
|
|
389
|
+
name: "Main Post Media",
|
|
390
|
+
widget: renderMediaWidget(url, isVideo),
|
|
391
|
+
url: url,
|
|
392
|
+
type: isVideo ? "video" : "image",
|
|
393
|
+
fileMediaTypeRR: postData.fileMediaTypeRR,
|
|
394
|
+
rsmguid: postData.rsmguid,
|
|
395
|
+
// Use the main post's rsmguid
|
|
396
|
+
isMainInclude: false
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// Other Assets
|
|
401
|
+
if (postData.otherAssets && postData.otherAssets.length > 0) {
|
|
402
|
+
postData.otherAssets.forEach(function (asset) {
|
|
403
|
+
var assetUrl = asset.otherAssetsPostImage;
|
|
404
|
+
var isVideo = isVideoFile(assetUrl, asset.otherAssetsFileMediaTypeRR);
|
|
405
|
+
previewsArray.push({
|
|
406
|
+
name: asset.otherAssetsFileFriendlyName || "Additional Media",
|
|
407
|
+
widget: renderMediaWidget(assetUrl, isVideo),
|
|
408
|
+
url: assetUrl,
|
|
409
|
+
type: isVideo ? "video" : "image",
|
|
410
|
+
fileMediaTypeRR: asset.otherAssetsFileMediaTypeRR,
|
|
411
|
+
rsmguid: asset.otherAssetsRSMGUID,
|
|
412
|
+
// Use the asset's rsmguid
|
|
413
|
+
isMainInclude: true
|
|
414
|
+
});
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
setPreviews(previewsArray);
|
|
418
|
+
|
|
419
|
+
// Initialize replacementFiles array to match previews array length
|
|
420
|
+
setReplacementFiles(new Array(previewsArray.length).fill(null));
|
|
421
|
+
}
|
|
422
|
+
}, [show, postData]);
|
|
423
|
+
|
|
424
|
+
// Cleanup effect for memory management
|
|
425
|
+
useEffect(function () {
|
|
426
|
+
return function () {
|
|
427
|
+
// Clean up any object URLs when component unmounts
|
|
428
|
+
replacementFiles.forEach(function (file) {
|
|
429
|
+
if (file && file.url) {
|
|
430
|
+
URL.revokeObjectURL(file.url);
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
};
|
|
434
|
+
}, [replacementFiles]);
|
|
435
|
+
var isVideoFile = function isVideoFile(url, fileMediaTypeRR) {
|
|
436
|
+
return fileMediaTypeRR === 82562;
|
|
437
|
+
};
|
|
438
|
+
var renderMediaWidget = function renderMediaWidget(url, isVideo) {
|
|
439
|
+
if (isVideo) {
|
|
440
|
+
return /*#__PURE__*/_jsx(VideoPlayer, {
|
|
441
|
+
src: url,
|
|
442
|
+
id: "edit-video-".concat(Date.now()),
|
|
443
|
+
autoPlay: true,
|
|
444
|
+
muted: true,
|
|
445
|
+
controls: true,
|
|
446
|
+
loop: true,
|
|
447
|
+
className: "media-item__video",
|
|
448
|
+
style: {
|
|
449
|
+
width: "100%",
|
|
450
|
+
height: "100%",
|
|
451
|
+
objectFit: "contain"
|
|
452
|
+
},
|
|
453
|
+
preloadStrategy: "balanced",
|
|
454
|
+
lowQualityFirst: false
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
return /*#__PURE__*/_jsx("img", {
|
|
458
|
+
className: "focused-img full-img",
|
|
459
|
+
src: url,
|
|
460
|
+
alt: "Media",
|
|
461
|
+
style: {
|
|
462
|
+
width: "100%",
|
|
463
|
+
height: "100%",
|
|
464
|
+
objectFit: "contain"
|
|
465
|
+
}
|
|
466
|
+
});
|
|
467
|
+
};
|
|
468
|
+
|
|
469
|
+
// Removed file addition functionality - only replacement is allowed
|
|
470
|
+
|
|
471
|
+
var ReplaceFile = function ReplaceFile(index, rsmguid, isMainInclude) {
|
|
472
|
+
singleEditInputFileChooserRef.current.click();
|
|
473
|
+
singleEditInputFileChooserRef.current.onchange = /*#__PURE__*/function () {
|
|
474
|
+
var _ref7 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6(event) {
|
|
475
|
+
var files, originalFile, processedFile, progressCallback, url, isVideo, newPreview, updatedPreviews, updatedReplacementFiles, _t7;
|
|
476
|
+
return _regenerator().w(function (_context6) {
|
|
477
|
+
while (1) switch (_context6.n) {
|
|
478
|
+
case 0:
|
|
479
|
+
files = Array.from(event.target.files);
|
|
480
|
+
if (!(files.length > 0)) {
|
|
481
|
+
_context6.n = 10;
|
|
482
|
+
break;
|
|
483
|
+
}
|
|
484
|
+
originalFile = files[0]; // Validate file size and type
|
|
485
|
+
if (!(originalFile.type.startsWith('video/') && originalFile.size > VIDEO_MAX_SIZE)) {
|
|
486
|
+
_context6.n = 1;
|
|
487
|
+
break;
|
|
488
|
+
}
|
|
489
|
+
setErrorMessage("Video \"".concat(originalFile.name, "\" is too large (").concat((originalFile.size / (1024 * 1024)).toFixed(2), " MB). Limit is 25MB."));
|
|
490
|
+
return _context6.a(2);
|
|
491
|
+
case 1:
|
|
492
|
+
if (!(!originalFile.type.startsWith('image/') && !originalFile.type.startsWith('video/'))) {
|
|
493
|
+
_context6.n = 2;
|
|
494
|
+
break;
|
|
495
|
+
}
|
|
496
|
+
setErrorMessage("Unsupported file type: ".concat(originalFile.type, ". Please select an image or video file."));
|
|
497
|
+
return _context6.a(2);
|
|
498
|
+
case 2:
|
|
499
|
+
setIsProcessing(true);
|
|
500
|
+
setProcessingProgress(0);
|
|
501
|
+
setProcessingDetails("Processing replacement file...");
|
|
502
|
+
setErrorMessage("");
|
|
503
|
+
_context6.p = 3;
|
|
504
|
+
processedFile = originalFile; // Progress callback for processing
|
|
505
|
+
progressCallback = function progressCallback(progress, details) {
|
|
506
|
+
setProcessingProgress(progress);
|
|
507
|
+
setProcessingDetails(details);
|
|
508
|
+
}; // Process based on file type
|
|
509
|
+
if (!originalFile.type.startsWith('image/')) {
|
|
510
|
+
_context6.n = 5;
|
|
511
|
+
break;
|
|
512
|
+
}
|
|
513
|
+
_context6.n = 4;
|
|
514
|
+
return convertToWebP(originalFile, progressCallback);
|
|
515
|
+
case 4:
|
|
516
|
+
processedFile = _context6.v;
|
|
517
|
+
_context6.n = 7;
|
|
518
|
+
break;
|
|
519
|
+
case 5:
|
|
520
|
+
if (!originalFile.type.startsWith('video/')) {
|
|
521
|
+
_context6.n = 7;
|
|
522
|
+
break;
|
|
523
|
+
}
|
|
524
|
+
_context6.n = 6;
|
|
525
|
+
return compressVideoWithFFmpeg(originalFile, progressCallback);
|
|
526
|
+
case 6:
|
|
527
|
+
processedFile = _context6.v;
|
|
528
|
+
case 7:
|
|
529
|
+
url = URL.createObjectURL(processedFile);
|
|
530
|
+
isVideo = processedFile.type.startsWith("video/"); // Create new preview using the renderMediaWidget function for consistency
|
|
531
|
+
newPreview = {
|
|
532
|
+
name: processedFile.name,
|
|
533
|
+
widget: renderMediaWidget(url, isVideo),
|
|
534
|
+
url: url,
|
|
535
|
+
type: isVideo ? "video" : "image",
|
|
536
|
+
fileMediaTypeRR: isVideo ? 82562 : 428,
|
|
537
|
+
originalSize: originalFile.size,
|
|
538
|
+
processedSize: processedFile.size
|
|
539
|
+
};
|
|
540
|
+
updatedPreviews = _toConsumableArray(previews);
|
|
541
|
+
updatedPreviews[index] = newPreview;
|
|
542
|
+
setPreviews(updatedPreviews);
|
|
543
|
+
|
|
544
|
+
// Force a re-render by updating the counter
|
|
545
|
+
setUpdateCounter(function (prev) {
|
|
546
|
+
return prev + 1;
|
|
547
|
+
});
|
|
548
|
+
|
|
549
|
+
// Store the processed file for upload
|
|
550
|
+
updatedReplacementFiles = _toConsumableArray(replacementFiles);
|
|
551
|
+
updatedReplacementFiles[index] = processedFile;
|
|
552
|
+
setReplacementFiles(updatedReplacementFiles);
|
|
553
|
+
if (isMainInclude) {
|
|
554
|
+
setDeletedEditedPost(function (prev) {
|
|
555
|
+
return [].concat(_toConsumableArray(prev), [{
|
|
556
|
+
rsmGUID: rsmguid
|
|
557
|
+
}]);
|
|
558
|
+
});
|
|
559
|
+
} else {
|
|
560
|
+
setUpdateMainthumbnail(true);
|
|
561
|
+
}
|
|
562
|
+
toast.success("File replaced successfully! ".concat(isVideo ? 'Video' : 'Image', " optimized."), {
|
|
563
|
+
position: "bottom-right",
|
|
564
|
+
autoClose: 3000
|
|
565
|
+
});
|
|
566
|
+
_context6.n = 9;
|
|
567
|
+
break;
|
|
568
|
+
case 8:
|
|
569
|
+
_context6.p = 8;
|
|
570
|
+
_t7 = _context6.v;
|
|
571
|
+
// File processing error
|
|
572
|
+
setErrorMessage("Failed to process the replacement file. Please try again.");
|
|
573
|
+
case 9:
|
|
574
|
+
_context6.p = 9;
|
|
575
|
+
setIsProcessing(false);
|
|
576
|
+
setProcessingProgress(0);
|
|
577
|
+
setProcessingDetails("");
|
|
578
|
+
return _context6.f(9);
|
|
579
|
+
case 10:
|
|
580
|
+
return _context6.a(2);
|
|
581
|
+
}
|
|
582
|
+
}, _callee6, null, [[3, 8, 9, 10]]);
|
|
583
|
+
}));
|
|
584
|
+
return function (_x6) {
|
|
585
|
+
return _ref7.apply(this, arguments);
|
|
586
|
+
};
|
|
587
|
+
}();
|
|
588
|
+
};
|
|
589
|
+
var deletefile = /*#__PURE__*/function () {
|
|
590
|
+
var _ref8 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee7(rsmguid, index) {
|
|
591
|
+
var updatedPreviews, updatedReplacementFiles;
|
|
592
|
+
return _regenerator().w(function (_context7) {
|
|
593
|
+
while (1) switch (_context7.n) {
|
|
594
|
+
case 0:
|
|
595
|
+
// Remove the specific item by index
|
|
596
|
+
updatedPreviews = previews.filter(function (_, i) {
|
|
597
|
+
return i !== index;
|
|
598
|
+
});
|
|
599
|
+
setPreviews(updatedPreviews);
|
|
600
|
+
|
|
601
|
+
// Remove the corresponding replacement file by index
|
|
602
|
+
updatedReplacementFiles = replacementFiles.filter(function (_, i) {
|
|
603
|
+
return i !== index;
|
|
604
|
+
});
|
|
605
|
+
setReplacementFiles(updatedReplacementFiles);
|
|
606
|
+
if (rsmguid && rsmguid !== "") {
|
|
607
|
+
setDeletedEditedPost(function (prev) {
|
|
608
|
+
return [].concat(_toConsumableArray(prev), [{
|
|
609
|
+
rsmGUID: rsmguid
|
|
610
|
+
}]);
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
case 1:
|
|
614
|
+
return _context7.a(2);
|
|
615
|
+
}
|
|
616
|
+
}, _callee7);
|
|
617
|
+
}));
|
|
618
|
+
return function deletefile(_x7, _x8) {
|
|
619
|
+
return _ref8.apply(this, arguments);
|
|
620
|
+
};
|
|
621
|
+
}();
|
|
622
|
+
var handleSubmit = /*#__PURE__*/function () {
|
|
623
|
+
var _ref9 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee8() {
|
|
624
|
+
var filesToUpload, _t8;
|
|
625
|
+
return _regenerator().w(function (_context8) {
|
|
626
|
+
while (1) switch (_context8.n) {
|
|
627
|
+
case 0:
|
|
628
|
+
if (!isProcessing) {
|
|
629
|
+
_context8.n = 1;
|
|
630
|
+
break;
|
|
631
|
+
}
|
|
632
|
+
setErrorMessage("Please wait for file processing to complete.");
|
|
633
|
+
return _context8.a(2);
|
|
634
|
+
case 1:
|
|
635
|
+
_context8.p = 1;
|
|
636
|
+
// Filter out any null/undefined files from replacement files
|
|
637
|
+
filesToUpload = replacementFiles.filter(function (file) {
|
|
638
|
+
return file && file.name;
|
|
639
|
+
});
|
|
640
|
+
_context8.n = 2;
|
|
641
|
+
return editPostApi(filesToUpload, deletedEditedPost, updateMainthumbnail);
|
|
642
|
+
case 2:
|
|
643
|
+
// Trigger image cache-busting to ensure fresh images
|
|
644
|
+
triggerImageCacheBust();
|
|
645
|
+
toast.success("Post updated successfully!", {
|
|
646
|
+
position: "bottom-right",
|
|
647
|
+
autoClose: 2000
|
|
648
|
+
});
|
|
649
|
+
handleModalClose();
|
|
650
|
+
|
|
651
|
+
// Give server time to process the image update
|
|
652
|
+
setTimeout(function () {
|
|
653
|
+
refreshData();
|
|
654
|
+
}, 1000);
|
|
655
|
+
_context8.n = 4;
|
|
656
|
+
break;
|
|
657
|
+
case 3:
|
|
658
|
+
_context8.p = 3;
|
|
659
|
+
_t8 = _context8.v;
|
|
660
|
+
// Error updating post
|
|
661
|
+
setErrorMessage("Failed to update post. Please try again.");
|
|
662
|
+
toast.error("Failed to update post. Please try again.", {
|
|
663
|
+
position: "bottom-right",
|
|
664
|
+
autoClose: 5000
|
|
665
|
+
});
|
|
666
|
+
case 4:
|
|
667
|
+
return _context8.a(2);
|
|
668
|
+
}
|
|
669
|
+
}, _callee8, null, [[1, 3]]);
|
|
670
|
+
}));
|
|
671
|
+
return function handleSubmit() {
|
|
672
|
+
return _ref9.apply(this, arguments);
|
|
673
|
+
};
|
|
674
|
+
}();
|
|
675
|
+
var handleModalClose = function handleModalClose() {
|
|
676
|
+
handleClose();
|
|
677
|
+
setReplacementFiles([]);
|
|
678
|
+
setErrorMessage("");
|
|
679
|
+
setIsProcessing(false);
|
|
680
|
+
setProcessingProgress(0);
|
|
681
|
+
setProcessingDetails("");
|
|
682
|
+
|
|
683
|
+
// Clean up any object URLs from replacement files
|
|
684
|
+
replacementFiles.forEach(function (file) {
|
|
685
|
+
if (file && file.url) {
|
|
686
|
+
URL.revokeObjectURL(file.url);
|
|
687
|
+
}
|
|
688
|
+
});
|
|
689
|
+
|
|
690
|
+
// CRITICAL: Trigger memory cleanup when modal closes
|
|
691
|
+
if (memoryManager) {
|
|
692
|
+
memoryManager.manualCleanup();
|
|
693
|
+
}
|
|
694
|
+
};
|
|
695
|
+
return /*#__PURE__*/_jsxs(Modal, {
|
|
696
|
+
size: "xl",
|
|
697
|
+
className: "edit-post-modal d-flex justify-content-center",
|
|
698
|
+
fullscreen: true,
|
|
699
|
+
show: show,
|
|
700
|
+
onHide: handleModalClose,
|
|
701
|
+
centered: true,
|
|
702
|
+
backdrop: "static",
|
|
703
|
+
children: [/*#__PURE__*/_jsx(Modal.Header, {
|
|
704
|
+
className: "enhanced-modal-header",
|
|
705
|
+
children: /*#__PURE__*/_jsxs("div", {
|
|
706
|
+
className: "d-flex justify-content-between align-items-center w-100",
|
|
707
|
+
children: [/*#__PURE__*/_jsxs("h4", {
|
|
708
|
+
className: "modal-title mb-0",
|
|
709
|
+
children: [/*#__PURE__*/_jsx("i", {
|
|
710
|
+
className: "fas fa-edit me-2"
|
|
711
|
+
}), "Edit Post"]
|
|
712
|
+
}), /*#__PURE__*/_jsxs("div", {
|
|
713
|
+
className: "d-flex gap-2",
|
|
714
|
+
children: [/*#__PURE__*/_jsxs(Button, {
|
|
715
|
+
id: "post-edit-btn",
|
|
716
|
+
variant: "primary",
|
|
717
|
+
size: "lg",
|
|
718
|
+
onClick: handleSubmit,
|
|
719
|
+
className: "enhanced-post-btn",
|
|
720
|
+
children: [/*#__PURE__*/_jsx("i", {
|
|
721
|
+
className: "fas fa-save me-2"
|
|
722
|
+
}), "Update Post"]
|
|
723
|
+
}), /*#__PURE__*/_jsxs(Button, {
|
|
724
|
+
variant: "outline-secondary",
|
|
725
|
+
size: "lg",
|
|
726
|
+
onClick: handleModalClose,
|
|
727
|
+
className: "enhanced-close-btn",
|
|
728
|
+
children: [/*#__PURE__*/_jsx("i", {
|
|
729
|
+
className: "fas fa-times me-2"
|
|
730
|
+
}), "Cancel"]
|
|
731
|
+
})]
|
|
732
|
+
})]
|
|
733
|
+
})
|
|
734
|
+
}), /*#__PURE__*/_jsx(Modal.Body, {
|
|
735
|
+
className: "enhanced-modal-body",
|
|
736
|
+
children: /*#__PURE__*/_jsxs(Container, {
|
|
737
|
+
className: "p-3",
|
|
738
|
+
children: [errorMessage && /*#__PURE__*/_jsx("div", {
|
|
739
|
+
className: "alert alert-danger enhanced-alert",
|
|
740
|
+
children: /*#__PURE__*/_jsxs("div", {
|
|
741
|
+
className: "d-flex align-items-center",
|
|
742
|
+
children: [/*#__PURE__*/_jsx("i", {
|
|
743
|
+
className: "fas fa-exclamation-triangle me-2"
|
|
744
|
+
}), /*#__PURE__*/_jsx("div", {
|
|
745
|
+
style: {
|
|
746
|
+
whiteSpace: 'pre-line'
|
|
747
|
+
},
|
|
748
|
+
children: errorMessage
|
|
749
|
+
})]
|
|
750
|
+
})
|
|
751
|
+
}), isProcessing && /*#__PURE__*/_jsxs("div", {
|
|
752
|
+
className: "alert alert-info enhanced-alert",
|
|
753
|
+
children: [/*#__PURE__*/_jsxs("div", {
|
|
754
|
+
className: "d-flex justify-content-between align-items-center",
|
|
755
|
+
children: [/*#__PURE__*/_jsxs("div", {
|
|
756
|
+
className: "d-flex align-items-center",
|
|
757
|
+
children: [/*#__PURE__*/_jsx("i", {
|
|
758
|
+
className: "fas fa-cog fa-spin me-2"
|
|
759
|
+
}), /*#__PURE__*/_jsx("span", {
|
|
760
|
+
children: "Processing media file..."
|
|
761
|
+
})]
|
|
762
|
+
}), /*#__PURE__*/_jsxs("span", {
|
|
763
|
+
className: "badge bg-primary",
|
|
764
|
+
children: [Math.round(processingProgress), "%"]
|
|
765
|
+
})]
|
|
766
|
+
}), processingDetails && /*#__PURE__*/_jsxs("div", {
|
|
767
|
+
className: "mt-2 small text-muted",
|
|
768
|
+
children: [/*#__PURE__*/_jsx("i", {
|
|
769
|
+
className: "fas fa-info-circle me-1"
|
|
770
|
+
}), processingDetails]
|
|
771
|
+
}), /*#__PURE__*/_jsx("div", {
|
|
772
|
+
className: "progress mt-2 enhanced-progress",
|
|
773
|
+
children: /*#__PURE__*/_jsx("div", {
|
|
774
|
+
className: "progress-bar progress-bar-striped progress-bar-animated",
|
|
775
|
+
role: "progressbar",
|
|
776
|
+
style: {
|
|
777
|
+
width: "".concat(processingProgress, "%")
|
|
778
|
+
},
|
|
779
|
+
"aria-valuenow": processingProgress,
|
|
780
|
+
"aria-valuemin": "0",
|
|
781
|
+
"aria-valuemax": "100"
|
|
782
|
+
})
|
|
783
|
+
})]
|
|
784
|
+
}), /*#__PURE__*/_jsxs("div", {
|
|
785
|
+
className: "enhanced-form-section",
|
|
786
|
+
children: [/*#__PURE__*/_jsx("div", {
|
|
787
|
+
className: "form-group mb-4",
|
|
788
|
+
children: /*#__PURE__*/_jsx(FloatingLabel, {
|
|
789
|
+
controlId: "edit-post-title",
|
|
790
|
+
label: "Post Title",
|
|
791
|
+
className: "enhanced-floating-label",
|
|
792
|
+
children: /*#__PURE__*/_jsx(Form.Control, {
|
|
793
|
+
type: "text",
|
|
794
|
+
className: "edit-post-title form-control-lg enhanced-input",
|
|
795
|
+
value: postTitle,
|
|
796
|
+
onChange: function onChange(e) {
|
|
797
|
+
return setPostTitle(e.target.value);
|
|
798
|
+
},
|
|
799
|
+
required: true,
|
|
800
|
+
placeholder: ""
|
|
801
|
+
})
|
|
802
|
+
})
|
|
803
|
+
}), /*#__PURE__*/_jsx("div", {
|
|
804
|
+
className: "form-group mb-4",
|
|
805
|
+
children: /*#__PURE__*/_jsx(FloatingLabel, {
|
|
806
|
+
controlId: "edit-post-content",
|
|
807
|
+
label: "What's on your mind?",
|
|
808
|
+
className: "enhanced-floating-label",
|
|
809
|
+
children: /*#__PURE__*/_jsx(Form.Control, {
|
|
810
|
+
as: "textarea",
|
|
811
|
+
className: "edit-post-text form-control-lg enhanced-input",
|
|
812
|
+
style: {
|
|
813
|
+
height: "120px",
|
|
814
|
+
resize: 'none'
|
|
815
|
+
},
|
|
816
|
+
value: postContent,
|
|
817
|
+
onChange: function onChange(e) {
|
|
818
|
+
return setPostContent(e.target.value);
|
|
819
|
+
},
|
|
820
|
+
required: true,
|
|
821
|
+
placeholder: ""
|
|
822
|
+
})
|
|
823
|
+
})
|
|
824
|
+
})]
|
|
825
|
+
}), previews.length > 0 ? /*#__PURE__*/_jsxs("div", {
|
|
826
|
+
className: "enhanced-media-preview mt-4",
|
|
827
|
+
children: [/*#__PURE__*/_jsxs("div", {
|
|
828
|
+
className: "d-flex justify-content-between align-items-center mb-3",
|
|
829
|
+
children: [/*#__PURE__*/_jsxs("h6", {
|
|
830
|
+
className: "mb-0",
|
|
831
|
+
children: [/*#__PURE__*/_jsx("i", {
|
|
832
|
+
className: "fas fa-images me-2"
|
|
833
|
+
}), "Media Preview (", previews.length, " file", previews.length > 1 ? 's' : '', ")"]
|
|
834
|
+
}), /*#__PURE__*/_jsx("small", {
|
|
835
|
+
className: "text-muted",
|
|
836
|
+
children: "Replace existing media only"
|
|
837
|
+
})]
|
|
838
|
+
}), /*#__PURE__*/_jsx("div", {
|
|
839
|
+
className: "enhanced-media-grid ".concat(previews.length === 1 ? 'single-item' : previews.length === 2 ? 'two-items' : previews.length === 3 ? 'three-items' : 'four-plus-items'),
|
|
840
|
+
children: previews.map(function (preview, index) {
|
|
841
|
+
return /*#__PURE__*/_jsxs("div", {
|
|
842
|
+
className: "enhanced-media-grid-item ".concat(index === 0 ? 'selected-thumbnail' : 'edit-mode'),
|
|
843
|
+
"data-edt-rsm": preview.rsmguid,
|
|
844
|
+
children: [/*#__PURE__*/_jsx("div", {
|
|
845
|
+
className: "enhanced-media-container",
|
|
846
|
+
children: preview.widget
|
|
847
|
+
}), index === 0 && /*#__PURE__*/_jsxs("div", {
|
|
848
|
+
className: "thumbnail-indicator",
|
|
849
|
+
children: [/*#__PURE__*/_jsx("i", {
|
|
850
|
+
className: "fas fa-star"
|
|
851
|
+
}), /*#__PURE__*/_jsx("span", {
|
|
852
|
+
children: "Main Media"
|
|
853
|
+
})]
|
|
854
|
+
}), /*#__PURE__*/_jsxs("div", {
|
|
855
|
+
className: "enhanced-media-controls",
|
|
856
|
+
children: [/*#__PURE__*/_jsxs(Button, {
|
|
857
|
+
className: "enhanced-thumbnail-btn",
|
|
858
|
+
"data-parent-rsm": preview.rsmguid,
|
|
859
|
+
"data-media-index": index,
|
|
860
|
+
variant: "outline-secondary",
|
|
861
|
+
onClick: function onClick() {
|
|
862
|
+
return ReplaceFile(index, preview.rsmguid, preview.isMainInclude);
|
|
863
|
+
},
|
|
864
|
+
title: "Replace this media",
|
|
865
|
+
size: "sm",
|
|
866
|
+
children: [/*#__PURE__*/_jsx("i", {
|
|
867
|
+
className: "fas fa-edit"
|
|
868
|
+
}), /*#__PURE__*/_jsx("small", {
|
|
869
|
+
className: "d-block mt-1",
|
|
870
|
+
children: "Replace"
|
|
871
|
+
})]
|
|
872
|
+
}), previews.length > 1 && index !== 0 && /*#__PURE__*/_jsxs(Button, {
|
|
873
|
+
className: "enhanced-delete-btn",
|
|
874
|
+
"data-media-index": index,
|
|
875
|
+
variant: "outline-danger",
|
|
876
|
+
onClick: function onClick() {
|
|
877
|
+
return deletefile(preview.rsmguid, index);
|
|
878
|
+
},
|
|
879
|
+
title: "Remove this media",
|
|
880
|
+
size: "sm",
|
|
881
|
+
children: [/*#__PURE__*/_jsx("i", {
|
|
882
|
+
className: "fas fa-trash-alt"
|
|
883
|
+
}), /*#__PURE__*/_jsx("small", {
|
|
884
|
+
className: "d-block mt-1",
|
|
885
|
+
children: "Remove"
|
|
886
|
+
})]
|
|
887
|
+
})]
|
|
888
|
+
})]
|
|
889
|
+
}, "".concat(preview.url, "-").concat(index, "-").concat(previews.length, "-").concat(updateCounter));
|
|
890
|
+
})
|
|
891
|
+
}), /*#__PURE__*/_jsx("input", {
|
|
892
|
+
type: "file",
|
|
893
|
+
ref: singleEditInputFileChooserRef,
|
|
894
|
+
className: "d-none",
|
|
895
|
+
accept: "video/*,image/*"
|
|
896
|
+
})]
|
|
897
|
+
}) : /*#__PURE__*/_jsx("div", {
|
|
898
|
+
className: "enhanced-empty-state mt-4",
|
|
899
|
+
children: /*#__PURE__*/_jsxs("div", {
|
|
900
|
+
className: "text-center py-4",
|
|
901
|
+
children: [/*#__PURE__*/_jsx("i", {
|
|
902
|
+
className: "fas fa-image fa-3x text-muted mb-3"
|
|
903
|
+
}), /*#__PURE__*/_jsx("p", {
|
|
904
|
+
className: "text-muted mb-0",
|
|
905
|
+
children: "No media files in this post"
|
|
906
|
+
}), /*#__PURE__*/_jsx("small", {
|
|
907
|
+
className: "text-muted",
|
|
908
|
+
children: "You can only edit text content when no media exists"
|
|
909
|
+
})]
|
|
910
|
+
})
|
|
911
|
+
})]
|
|
912
|
+
})
|
|
913
|
+
})]
|
|
914
|
+
});
|
|
915
|
+
};
|
|
916
|
+
export default EditPostModal;
|