Loading data/template/default/editor.html +65 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,10 @@ PUBLISHED: '${I18N_PUBLISHED}', VIEW: '${I18N_VIEW}', PUBLISH_FAILED: '${I18N_PUBLISH_FAILED}', SHARE_URL_REQUIRED: '${I18N_SHARE_URL_REQUIRED}', SHARING: '${I18N_SHARING}', SHARED: '${I18N_SHARED}', SHARE_FAILED: '${I18N_SHARE_FAILED}', ENTER_URL: '${I18N_ENTER_URL}', ADD_ELEMENT_TITLE: '${I18N_ADD_ELEMENT_TITLE}', BOLD: '${I18N_BOLD}', Loading Loading @@ -593,6 +597,24 @@ </div> </div> <!-- Share to Social Section --> <div class="tpl-section border-t border-gray-600 pt-4 mt-4"> <div class="flex justify-between items-center mb-2"> <h3 class="font-bold text-blue-400">${I18N_SHARE_SOCIAL}</h3> <button class="tpl-btn" style="background:#1877f2;color:#fff;" onclick="toggleSharePanel()" title="${I18N_SHARE_SOCIAL}">📢 ${I18N_SHARE}</button> </div> <div id="share-panel" style="display:none;"> <label class="text-xs text-gray-300 block mb-1">${I18N_SHARE_URL}</label> <input class="prop-input" type="url" id="share-url" placeholder="https://..." required> <label class="text-xs text-gray-300 block mt-2 mb-1">${I18N_SHARE_TITLE}</label> <input class="prop-input" type="text" id="share-title" placeholder="${I18N_SHARE_TITLE_PH}"> <label class="text-xs text-gray-300 block mt-2 mb-1">${I18N_SHARE_DESC}</label> <textarea class="prop-textarea" id="share-description" placeholder="${I18N_SHARE_DESC_PH}"></textarea> <button class="tpl-btn tpl-btn-primary mt-3" style="background:#1877f2;" onclick="doSharePost()">📢 ${I18N_SHARE_NOW}</button> <div id="share-status" class="prop-status mt-1"></div> </div> </div> <!-- Document Tree View / Content Index --> <div id="document-tree" class="mt-6 pt-4 border-t border-gray-600"> <div class="flex justify-between items-center mb-2"> Loading Loading @@ -2724,6 +2746,49 @@ } } // --- Share to Social --- function toggleSharePanel() { const panel = document.getElementById('share-panel'); panel.style.display = panel.style.display === 'none' ? 'block' : 'none'; } async function doSharePost() { const statusEl = document.getElementById('share-status'); const url = document.getElementById('share-url').value.trim(); const title = document.getElementById('share-title').value.trim(); const description = document.getElementById('share-description').value.trim(); if (!url) { statusEl.textContent = I18N.SHARE_URL_REQUIRED; statusEl.className = 'prop-status error'; return; } statusEl.textContent = I18N.SHARING; statusEl.className = 'prop-status'; try { const result = await sendApiRequest([{ command: 'share_post', url: url, title: title, description: description }]); const resp = result[0]; if (resp.status === 'success') { statusEl.textContent = '\u2714 ' + I18N.SHARED; statusEl.className = 'prop-status success'; } else { statusEl.textContent = resp.message || I18N.SHARE_FAILED; statusEl.className = 'prop-status error'; } } catch (e) { statusEl.textContent = 'Error: ' + e.message; statusEl.className = 'prop-status error'; } } // --- Event Listeners --- // PostMessage Listener: Captures clicks/events from the rendered iframe Loading src/edit.cpp +31 −0 Original line number Diff line number Diff line Loading @@ -2585,6 +2585,37 @@ void blogi::webedit::WebEditor::JsonApi(const int tid, json_object *request, jso } } handled = true; } else if (strcmp(command, "share_post") == 0) { // Manually share a URL to social networks via sharePost broadcast std::string shareUrl, shareTitle, shareDesc; json_object *param_obj = nullptr; if (json_object_object_get_ex(single_request, "url", ¶m_obj)) { const char *v = json_object_get_string(param_obj); if (v) shareUrl = v; } if (json_object_object_get_ex(single_request, "title", ¶m_obj)) { const char *v = json_object_get_string(param_obj); if (v) shareTitle = v; } if (json_object_object_get_ex(single_request, "description", ¶m_obj)) { const char *v = json_object_get_string(param_obj); if (v) shareDesc = v; } if (shareUrl.empty()) { json_object_object_add(single_response, "status", json_object_new_string("error")); json_object_object_add(single_response, "message", json_object_new_string("Missing 'url' parameter.")); } else { if (plugins) { for (const Plugin::PluginData *splg = plugins->getFirstPlugin(); splg; splg = splg->getNextPlg()) { splg->getInstace()->sharePost(tid, ShareText, shareUrl, shareTitle, shareDesc); } } json_object_object_add(single_response, "status", json_object_new_string("success")); json_object_object_add(single_response, "message", json_object_new_string("Shared successfully.")); } handled = true; } Loading src/translations.h +28 −0 Original line number Diff line number Diff line Loading @@ -313,6 +313,20 @@ namespace blogi { {"I18N_PUBLISHED", "Erfolgreich veröffentlicht!"}, {"I18N_VIEW", "Ansehen"}, {"I18N_PUBLISH_FAILED", "Veröffentlichung fehlgeschlagen."}, // Share to Social {"I18N_SHARE_SOCIAL", "Auf Social Media teilen"}, {"I18N_SHARE", "Teilen"}, {"I18N_SHARE_URL", "URL"}, {"I18N_SHARE_TITLE", "Titel"}, {"I18N_SHARE_TITLE_PH", "Beitragstitel"}, {"I18N_SHARE_DESC", "Beschreibung"}, {"I18N_SHARE_DESC_PH", "Kurze Beschreibung des Beitrags"}, {"I18N_SHARE_NOW", "Jetzt teilen"}, {"I18N_SHARING", "Wird geteilt..."}, {"I18N_SHARED", "Erfolgreich geteilt!"}, {"I18N_SHARE_FAILED", "Teilen fehlgeschlagen."}, {"I18N_SHARE_URL_REQUIRED", "URL ist erforderlich."}, {"Shared successfully.", "Erfolgreich geteilt."}, {"I18N_ADD_ELEMENT_TITLE", "Element hinzufügen"}, {"I18N_BOLD", "Fett"}, {"I18N_ITALIC", "Kursiv"}, Loading Loading @@ -684,6 +698,20 @@ namespace blogi { {"I18N_SAVE_BTN", "Save"}, {"I18N_CUSTOM_COLOR", "Custom Color"}, {"I18N_THEME_VARIABLE", "Theme Variable"}, // Share to Social {"I18N_SHARE_SOCIAL", "Share to Social Media"}, {"I18N_SHARE", "Share"}, {"I18N_SHARE_URL", "URL"}, {"I18N_SHARE_TITLE", "Title"}, {"I18N_SHARE_TITLE_PH", "Post title"}, {"I18N_SHARE_DESC", "Description"}, {"I18N_SHARE_DESC_PH", "Short description of the post"}, {"I18N_SHARE_NOW", "Share Now"}, {"I18N_SHARING", "Sharing..."}, {"I18N_SHARED", "Shared successfully!"}, {"I18N_SHARE_FAILED", "Sharing failed."}, {"I18N_SHARE_URL_REQUIRED", "URL is required."}, {"Shared successfully.", "Shared successfully."}, // Cookie banner {"Accept", "Accept"}, {"Technical Required", "Technical Required"}, Loading Loading
data/template/default/editor.html +65 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,10 @@ PUBLISHED: '${I18N_PUBLISHED}', VIEW: '${I18N_VIEW}', PUBLISH_FAILED: '${I18N_PUBLISH_FAILED}', SHARE_URL_REQUIRED: '${I18N_SHARE_URL_REQUIRED}', SHARING: '${I18N_SHARING}', SHARED: '${I18N_SHARED}', SHARE_FAILED: '${I18N_SHARE_FAILED}', ENTER_URL: '${I18N_ENTER_URL}', ADD_ELEMENT_TITLE: '${I18N_ADD_ELEMENT_TITLE}', BOLD: '${I18N_BOLD}', Loading Loading @@ -593,6 +597,24 @@ </div> </div> <!-- Share to Social Section --> <div class="tpl-section border-t border-gray-600 pt-4 mt-4"> <div class="flex justify-between items-center mb-2"> <h3 class="font-bold text-blue-400">${I18N_SHARE_SOCIAL}</h3> <button class="tpl-btn" style="background:#1877f2;color:#fff;" onclick="toggleSharePanel()" title="${I18N_SHARE_SOCIAL}">📢 ${I18N_SHARE}</button> </div> <div id="share-panel" style="display:none;"> <label class="text-xs text-gray-300 block mb-1">${I18N_SHARE_URL}</label> <input class="prop-input" type="url" id="share-url" placeholder="https://..." required> <label class="text-xs text-gray-300 block mt-2 mb-1">${I18N_SHARE_TITLE}</label> <input class="prop-input" type="text" id="share-title" placeholder="${I18N_SHARE_TITLE_PH}"> <label class="text-xs text-gray-300 block mt-2 mb-1">${I18N_SHARE_DESC}</label> <textarea class="prop-textarea" id="share-description" placeholder="${I18N_SHARE_DESC_PH}"></textarea> <button class="tpl-btn tpl-btn-primary mt-3" style="background:#1877f2;" onclick="doSharePost()">📢 ${I18N_SHARE_NOW}</button> <div id="share-status" class="prop-status mt-1"></div> </div> </div> <!-- Document Tree View / Content Index --> <div id="document-tree" class="mt-6 pt-4 border-t border-gray-600"> <div class="flex justify-between items-center mb-2"> Loading Loading @@ -2724,6 +2746,49 @@ } } // --- Share to Social --- function toggleSharePanel() { const panel = document.getElementById('share-panel'); panel.style.display = panel.style.display === 'none' ? 'block' : 'none'; } async function doSharePost() { const statusEl = document.getElementById('share-status'); const url = document.getElementById('share-url').value.trim(); const title = document.getElementById('share-title').value.trim(); const description = document.getElementById('share-description').value.trim(); if (!url) { statusEl.textContent = I18N.SHARE_URL_REQUIRED; statusEl.className = 'prop-status error'; return; } statusEl.textContent = I18N.SHARING; statusEl.className = 'prop-status'; try { const result = await sendApiRequest([{ command: 'share_post', url: url, title: title, description: description }]); const resp = result[0]; if (resp.status === 'success') { statusEl.textContent = '\u2714 ' + I18N.SHARED; statusEl.className = 'prop-status success'; } else { statusEl.textContent = resp.message || I18N.SHARE_FAILED; statusEl.className = 'prop-status error'; } } catch (e) { statusEl.textContent = 'Error: ' + e.message; statusEl.className = 'prop-status error'; } } // --- Event Listeners --- // PostMessage Listener: Captures clicks/events from the rendered iframe Loading
src/edit.cpp +31 −0 Original line number Diff line number Diff line Loading @@ -2585,6 +2585,37 @@ void blogi::webedit::WebEditor::JsonApi(const int tid, json_object *request, jso } } handled = true; } else if (strcmp(command, "share_post") == 0) { // Manually share a URL to social networks via sharePost broadcast std::string shareUrl, shareTitle, shareDesc; json_object *param_obj = nullptr; if (json_object_object_get_ex(single_request, "url", ¶m_obj)) { const char *v = json_object_get_string(param_obj); if (v) shareUrl = v; } if (json_object_object_get_ex(single_request, "title", ¶m_obj)) { const char *v = json_object_get_string(param_obj); if (v) shareTitle = v; } if (json_object_object_get_ex(single_request, "description", ¶m_obj)) { const char *v = json_object_get_string(param_obj); if (v) shareDesc = v; } if (shareUrl.empty()) { json_object_object_add(single_response, "status", json_object_new_string("error")); json_object_object_add(single_response, "message", json_object_new_string("Missing 'url' parameter.")); } else { if (plugins) { for (const Plugin::PluginData *splg = plugins->getFirstPlugin(); splg; splg = splg->getNextPlg()) { splg->getInstace()->sharePost(tid, ShareText, shareUrl, shareTitle, shareDesc); } } json_object_object_add(single_response, "status", json_object_new_string("success")); json_object_object_add(single_response, "message", json_object_new_string("Shared successfully.")); } handled = true; } Loading
src/translations.h +28 −0 Original line number Diff line number Diff line Loading @@ -313,6 +313,20 @@ namespace blogi { {"I18N_PUBLISHED", "Erfolgreich veröffentlicht!"}, {"I18N_VIEW", "Ansehen"}, {"I18N_PUBLISH_FAILED", "Veröffentlichung fehlgeschlagen."}, // Share to Social {"I18N_SHARE_SOCIAL", "Auf Social Media teilen"}, {"I18N_SHARE", "Teilen"}, {"I18N_SHARE_URL", "URL"}, {"I18N_SHARE_TITLE", "Titel"}, {"I18N_SHARE_TITLE_PH", "Beitragstitel"}, {"I18N_SHARE_DESC", "Beschreibung"}, {"I18N_SHARE_DESC_PH", "Kurze Beschreibung des Beitrags"}, {"I18N_SHARE_NOW", "Jetzt teilen"}, {"I18N_SHARING", "Wird geteilt..."}, {"I18N_SHARED", "Erfolgreich geteilt!"}, {"I18N_SHARE_FAILED", "Teilen fehlgeschlagen."}, {"I18N_SHARE_URL_REQUIRED", "URL ist erforderlich."}, {"Shared successfully.", "Erfolgreich geteilt."}, {"I18N_ADD_ELEMENT_TITLE", "Element hinzufügen"}, {"I18N_BOLD", "Fett"}, {"I18N_ITALIC", "Kursiv"}, Loading Loading @@ -684,6 +698,20 @@ namespace blogi { {"I18N_SAVE_BTN", "Save"}, {"I18N_CUSTOM_COLOR", "Custom Color"}, {"I18N_THEME_VARIABLE", "Theme Variable"}, // Share to Social {"I18N_SHARE_SOCIAL", "Share to Social Media"}, {"I18N_SHARE", "Share"}, {"I18N_SHARE_URL", "URL"}, {"I18N_SHARE_TITLE", "Title"}, {"I18N_SHARE_TITLE_PH", "Post title"}, {"I18N_SHARE_DESC", "Description"}, {"I18N_SHARE_DESC_PH", "Short description of the post"}, {"I18N_SHARE_NOW", "Share Now"}, {"I18N_SHARING", "Sharing..."}, {"I18N_SHARED", "Shared successfully!"}, {"I18N_SHARE_FAILED", "Sharing failed."}, {"I18N_SHARE_URL_REQUIRED", "URL is required."}, {"Shared successfully.", "Shared successfully."}, // Cookie banner {"Accept", "Accept"}, {"Technical Required", "Technical Required"}, Loading