Commit 3761373e authored by jan.koester's avatar jan.koester
Browse files

test

parent 687cb4e6
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -376,6 +376,40 @@ body {
    background: var(--accent-hover);
}

/* Property panel tabs */
.prop-tabs {
    display: flex;
    border-bottom: 1px solid var(--border);
    margin-bottom: 8px;
}

.prop-tab {
    flex: 1;
    padding: 6px 8px;
    background: none;
    color: var(--text-secondary);
    border: none;
    border-bottom: 2px solid transparent;
    cursor: pointer;
    font-size: 12px;
    font-weight: 500;
    transition: all 0.15s;
}

.prop-tab:hover {
    color: var(--text-primary);
    background: var(--bg-tertiary);
}

.prop-tab.active {
    color: var(--accent);
    border-bottom-color: var(--accent);
}

.prop-panel {
    padding-top: 4px;
}

/* Dialogs */
dialog {
    background: var(--bg-secondary);
+80 −16
Original line number Diff line number Diff line
@@ -54,6 +54,46 @@ var PropertiesPanel = (function() {
            return;
        }

        // Classify fields by target
        var desktopFields = [];
        var mobileFields = [];
        for (var i = 0; i < schema.length; i++) {
            var t = schema[i].target || 'all';
            if (t === 'mobile') {
                mobileFields.push(schema[i]);
            } else {
                desktopFields.push(schema[i]);
            }
        }

        // Tab bar
        var tabBar = document.createElement('div');
        tabBar.className = 'prop-tabs';
        var tabs = [
            { id: 'desktop', label: '\uD83D\uDDA5 Desktop' },
            { id: 'mobile',  label: '\uD83D\uDCF1 Mobile' }
        ];
        var panels = {};

        for (var ti = 0; ti < tabs.length; ti++) {
            var tabBtn = document.createElement('button');
            tabBtn.type = 'button';
            tabBtn.className = 'prop-tab' + (ti === 0 ? ' active' : '');
            tabBtn.textContent = tabs[ti].label;
            tabBtn.setAttribute('data-tab', tabs[ti].id);
            tabBtn.addEventListener('click', function() {
                var allTabs = tabBar.querySelectorAll('.prop-tab');
                for (var k = 0; k < allTabs.length; k++) allTabs[k].classList.remove('active');
                this.classList.add('active');
                var target = this.getAttribute('data-tab');
                for (var pid in panels) {
                    panels[pid].style.display = (pid === target) ? '' : 'none';
                }
            });
            tabBar.appendChild(tabBtn);
        }
        container.appendChild(tabBar);

        var form = document.createElement('form');
        form.id = 'prop-form';
        form.addEventListener('submit', function(e) {
@@ -61,8 +101,34 @@ var PropertiesPanel = (function() {
            saveProperties();
        });

        for (var i = 0; i < schema.length; i++) {
            var field = schema[i];
        // Create panels
        var desktopPanel = document.createElement('div');
        desktopPanel.className = 'prop-panel';
        panels['desktop'] = desktopPanel;

        var mobilePanel = document.createElement('div');
        mobilePanel.className = 'prop-panel';
        mobilePanel.style.display = 'none';
        panels['mobile'] = mobilePanel;

        _renderFieldsInto(desktopPanel, desktopFields, properties, form);
        _renderFieldsInto(mobilePanel, mobileFields, properties, form);

        form.appendChild(desktopPanel);
        form.appendChild(mobilePanel);

        var saveBtn = document.createElement('button');
        saveBtn.type = 'submit';
        saveBtn.className = 'prop-save-btn';
        saveBtn.textContent = 'Speichern';
        form.appendChild(saveBtn);

        container.appendChild(form);
    }

    function _renderFieldsInto(panel, fields, properties, form) {
        for (var i = 0; i < fields.length; i++) {
            var field = fields[i];
            var group = document.createElement('div');
            group.className = 'prop-group';

@@ -81,9 +147,6 @@ var PropertiesPanel = (function() {
            } else {
                var label = document.createElement('label');
                label.textContent = field.label;
                if (field.target && field.target !== 'all') {
                    label.textContent += ' (' + field.target + ')';
                }
                group.appendChild(label);

                var input;
@@ -143,7 +206,7 @@ var PropertiesPanel = (function() {
                    wrapper.appendChild(input);
                    wrapper.appendChild(browseBtn);
                    group.appendChild(wrapper);
                    form.appendChild(group);
                    panel.appendChild(group);
                    continue;
                } else {
                    input = document.createElement('input');
@@ -156,16 +219,8 @@ var PropertiesPanel = (function() {
                group.appendChild(input);
            }

            form.appendChild(group);
            panel.appendChild(group);
        }

        var saveBtn = document.createElement('button');
        saveBtn.type = 'submit';
        saveBtn.className = 'prop-save-btn';
        saveBtn.textContent = 'Speichern';
        form.appendChild(saveBtn);

        container.appendChild(form);
    }

    function saveProperties() {
@@ -185,7 +240,16 @@ var PropertiesPanel = (function() {
            }
        }

        EditorApi.setProperties(currentUuid, properties).then(function() {
        EditorApi.setProperties(currentUuid, properties).then(function(resp) {
            // Update form fields with computed dimensions from blog
            if (resp && resp.real_width) {
                var rwInput = form.querySelector('input[name="real_width"]');
                if (rwInput) rwInput.value = resp.real_width;
            }
            if (resp && resp.real_height) {
                var rhInput = form.querySelector('input[name="real_height"]');
                if (rhInput) rhInput.value = resp.real_height;
            }
            // Refresh preview after property change
            if (typeof Preview !== 'undefined') {
                Preview.refresh();
+46 −7
Original line number Diff line number Diff line
@@ -712,18 +712,18 @@ void webedit::Api::handleSetProperties(libhttppp::HttpRequest &curreq,

    // If properties contain media_id + real_width/real_height, register
    // the preview size with the blog so media/getimage allows it.
    // When only one dimension is given, compute the other from the aspect ratio.
    json_object *propsObj = nullptr;
    if (json_object_object_get_ex(reqJson, "properties", &propsObj)) {
        json_object *midObj = nullptr, *rwObj = nullptr, *rhObj = nullptr;
        if (json_object_object_get_ex(propsObj, "media_id", &midObj) &&
            json_object_object_get_ex(propsObj, "real_width", &rwObj)) {
            std::string mediaId = json_object_get_string(midObj);
            int rw = json_object_get_int(rwObj);
            int rh = 0;
        if (json_object_object_get_ex(propsObj, "media_id", &midObj)) {
            std::string mediaId = midObj ? json_object_get_string(midObj) : "";
            int rw = 0, rh = 0;
            if (json_object_object_get_ex(propsObj, "real_width", &rwObj))
                rw = json_object_get_int(rwObj);
            if (json_object_object_get_ex(propsObj, "real_height", &rhObj))
                rh = json_object_get_int(rhObj);
            if (!mediaId.empty() && (rw > 0 || rh > 0)) {
                // Fire-and-forget: register preview size via first active connection
                std::string authid, blogUrl;
                {
                    std::lock_guard<std::mutex> clk(_connSessionMtx);
@@ -747,7 +747,46 @@ void webedit::Api::handleSetProperties(libhttppp::HttpRequest &curreq,
                        json_object_array_add(apiArr, cmd);
                        json_object *apiResp = blogApiCall(blogUrl, apiArr);
                        json_object_put(apiArr);
                        if (apiResp) json_object_put(apiResp);
                        if (apiResp) {
                            // Extract actual dimensions from blog response and
                            // update the widget if a dimension was missing.
                            if (json_object_is_type(apiResp, json_type_array)) {
                                size_t len = json_object_array_length(apiResp);
                                for (size_t i = 0; i < len; ++i) {
                                    json_object *item = json_object_array_get_idx(apiResp, i);
                                    json_object *aw = nullptr, *ah = nullptr;
                                    json_object_object_get_ex(item, "width", &aw);
                                    json_object_object_get_ex(item, "height", &ah);
                                    if (aw && ah) {
                                        int actualW = json_object_get_int(aw);
                                        int actualH = json_object_get_int(ah);
                                        if ((rw <= 0 || rh <= 0) && actualW > 0 && actualH > 0) {
                                            // Update widget with computed dimensions
                                            json_object *fixReq = json_object_new_object();
                                            json_object_object_add(fixReq, "action",
                                                json_object_new_string("modify_bulk"));
                                            json_object *fixProps = json_object_new_object();
                                            json_object_object_add(fixProps, "real_width",
                                                json_object_new_int(actualW));
                                            json_object_object_add(fixProps, "real_height",
                                                json_object_new_int(actualH));
                                            json_object_object_add(fixReq, "properties", fixProps);
                                            json_object *fixResp = json_object_new_object();
                                            el->JsonApi(fixReq, fixResp);
                                            // Include computed dimensions in response
                                            json_object_object_add(respJson, "real_width",
                                                json_object_new_int(actualW));
                                            json_object_object_add(respJson, "real_height",
                                                json_object_new_int(actualH));
                                            json_object_put(fixReq);
                                            json_object_put(fixResp);
                                        }
                                        break;
                                    }
                                }
                            }
                            json_object_put(apiResp);
                        }
                    } catch (...) {
                        // Best effort — don't fail the property save
                    }