Skip to content

Commit

Permalink
chore: cleanup and fix bg image url (#970)
Browse files Browse the repository at this point in the history
* chore: cleanup and fix bg image url

* chore: add basic docs
  • Loading branch information
Caele committed Oct 20, 2022
1 parent 5907701 commit 520f053
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 71 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"jest/globals": true
},
"parserOptions": {
"sourceType": "module"
"sourceType": "module",
"ecmaVersion": 2020
},
"extends": ["airbnb", "prettier"],
"plugins": ["prettier", "jest"],
Expand Down
38 changes: 18 additions & 20 deletions apis/nucleus/src/components/Cell.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,17 @@ const loadType = async ({ dispatch, types, visualization, version, model, app, s
return undefined;
};

const resolveBgColor = (bgComp, theme) => {
const bgColor = bgComp?.bgColor;
if (bgColor && theme) {
if (bgColor.useColorExpression) {
return theme.validateColor(bgColor.colorExpression);
}
return bgColor.color && bgColor.color.color !== 'none' ? theme.getColorPickerColor(bgColor.color) : undefined;
}
return undefined;
};

const Cell = forwardRef(
({ halo, model, initialSnOptions, initialSnPlugins, initialError, onMount, currentId }, ref) => {
const { app, types } = halo;
Expand All @@ -298,31 +309,18 @@ const Cell = forwardRef(
},
});

const resolveBgColor = () => {
const bgComp = layout && layout.components ? layout.components.find((comp) => comp.key === 'general') : null;

if (bgComp && bgComp.bgColor && bgComp.bgColor.useColorExpression) {
if (bgComp.bgColor.colorExpression) {
bgComp.bgColor.colorExpression = { color: bgComp.bgColor.colorExpression };
}
return bgComp.bgColor.colorExpression
? halo.public.theme.getColorPickerColor(bgComp.bgColor.colorExpression)
: undefined;
}
if (bgComp && bgComp.bgColor && !bgComp.bgColor.useColorExpression)
return bgComp.bgColor.color && bgComp.bgColor.color.color !== 'none'
? halo.public.theme.getColorPickerColor(bgComp.bgColor.color)
: undefined;
return undefined;
};

useEffect(() => {
eventmixin(focusHandler.current);
}, []);

useEffect(() => {
setBgColor(resolveBgColor());
}, [layout, theme]);
setBgColor(
resolveBgColor(
layout && layout.components ? layout.components.find((comp) => comp.key === 'general') : null,
halo.public.theme
)
);
}, [layout, halo.public.theme]);

focusHandler.current.blurCallback = (resetFocus) => {
halo.root.toggleFocusOfCells();
Expand Down
142 changes: 92 additions & 50 deletions apis/nucleus/src/components/Supernova.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,89 @@ const VizElement = {
className: 'njs-viz',
};

const imageSizingToCssProperty = {
originalSize: 'auto auto',
alwaysFit: 'contain',
fitWidth: '100% auto',
fitHeight: 'auto 100%',
stretchFit: '100% 100%',
alwaysFill: 'cover',
};

const positionToCss = {
'top-left': 'top left',
'top-center': 'top center',
'top-right': 'top right',
'center-left': 'center left',
'center-center': 'center center',
'center-right': 'center right',
'bottom-left': 'bottom left',
'bottom-center': 'bottom center',
'bottom-right': 'bottom right',
};

// TODO: this needs some proper verification
function getSenseServerUrl(app) {
let config;
let wsUrl;
let protocol;
let isSecure;

if (app?.session?.config) {
config = app.session.config;
wsUrl = new URL(config.url);

isSecure = wsUrl.protocol === 'wss:';
protocol = isSecure ? 'https://' : 'http://';
return protocol + wsUrl.host;
}
return undefined;
}

function getBackgroundPosition(bgComp) {
let bkgImagePosition = 'center center';
if (bgComp?.bgImage?.position) {
bkgImagePosition = positionToCss[bgComp.bgImage.position];
}
return bkgImagePosition;
}

function getBackgroundSize(bgComp) {
let bkgImageSize = imageSizingToCssProperty.originalSize;
if (bgComp?.bgImage?.sizing) {
bkgImageSize = imageSizingToCssProperty[bgComp.bgImage.sizing];
}
return bkgImageSize;
}

function resolveImageUrl(app, relativeUrl) {
return relativeUrl ? getSenseServerUrl(app) + relativeUrl : undefined;
}

const resolveBgImage = (bgComp, app) => {
const bgImageDef = bgComp?.bgImage;

if (bgImageDef) {
let url = '';
if (bgImageDef.mode === 'media') {
url = bgImageDef?.mediaUrl?.qStaticContentUrl?.qUrl
? decodeURIComponent(bgImageDef.mediaUrl.qStaticContentUrl.qUrl)
: undefined;
url = resolveImageUrl(app, url);
}
if (bgImageDef.mode === 'expression') {
url = bgImageDef.expressionUrl ? decodeURIComponent(bgImageDef.expressionUrl) : undefined;
}
const pos = getBackgroundPosition(bgComp);
const size = getBackgroundSize(bgComp);

// TODO: need to resolve the URL by the WS path

return url ? { url, pos, size } : undefined;
}
return undefined;
};

function Supernova({ sn, snOptions: options, snPlugins: plugins, layout, appLayout, halo }) {
const { component } = sn;

Expand All @@ -28,29 +111,15 @@ function Supernova({ sn, snOptions: options, snPlugins: plugins, layout, appLayo
const [renderCnt, setRenderCnt] = useState(0);
const [containerRef, containerRect, containerNode] = useRect();
const [snNode, setSnNode] = useState(null);
const [bgImage, setBgImage] = useState(undefined);
const [bgComp, setBgComp] = useState(null);
const [bgImage, setBgImage] = useState(undefined); // {url: "", size: "", pos: ""}

const snRef = useCallback((ref) => {
if (!ref) {
return;
}
setSnNode(ref);
}, []);

const resolveBgImage = () => {
const bgImageDef = bgComp && bgComp.bgImage ? bgComp.bgImage : null;

if (bgImageDef && bgImageDef.mode === 'media') {
return bgImageDef.mediaUrl && bgImageDef.mediaUrl.qStaticContentUrl && bgImageDef.mediaUrl.qStaticContentUrl.qUrl
? decodeURIComponent(bgImageDef.mediaUrl.qStaticContentUrl.qUrl)
: undefined;
}
if (bgImageDef && bgImageDef.mode === 'expression') {
return bgImageDef.expressionUrl ? decodeURIComponent(bgImageDef.expressionUrl) : undefined;
}
return undefined;
};

// Mount / Unmount
useEffect(() => {
if (!snNode) return undefined;
Expand All @@ -65,12 +134,10 @@ function Supernova({ sn, snOptions: options, snPlugins: plugins, layout, appLayo

// Resolve Background Image
useEffect(() => {
setBgComp(layout && layout.components ? layout.components.find((comp) => comp.key === 'general') : null);
}, [layout]);

useEffect(() => {
setBgImage(resolveBgImage(bgComp));
}, [bgComp]);
setBgImage(
resolveBgImage(layout?.components ? layout.components.find((comp) => comp.key === 'general') : null, halo.app)
);
}, [layout, halo.app]);

// Render
useEffect(() => {
Expand Down Expand Up @@ -144,42 +211,17 @@ function Supernova({ sn, snOptions: options, snPlugins: plugins, layout, appLayo
keyboardNavigation,
]);

const imageSizingToCssProperty = {
originalSize: 'auto auto',
alwaysFit: 'contain',
fitWidth: '100% auto',
fitHeight: 'auto 100%',
stretchFit: '100% 100%',
alwaysFill: 'cover',
};

function getBackgroundPosition() {
let bkgImagePosition = 'center center';
if (bgComp && bgComp.bgImage && bgComp.bgImage.position) {
bkgImagePosition = bgComp.bgImage.position.replace('-', ' ');
}
return bkgImagePosition;
}

function getBackgroundSize() {
let bkgImageSize = imageSizingToCssProperty.originalSize;
if (bgComp && bgComp.bgImage && bgComp.bgImage.position) {
bkgImageSize = imageSizingToCssProperty[bgComp.bgImage.sizing];
}
return bkgImageSize;
}

return (
<div
ref={containerRef}
data-render-count={renderCnt}
style={{
position: 'relative',
height: '100%',
backgroundImage: `url(${bgImage})`,
backgroundImage: bgImage && bgImage.url ? `url(${bgImage.url})` : undefined,
backgroundRepeat: 'no-repeat',
backgroundSize: getBackgroundSize(),
backgroundPosition: getBackgroundPosition(),
backgroundSize: bgImage && bgImage.size,
backgroundPosition: bgImage && bgImage.pos,
}}
className={VizElement.className}
>
Expand Down
17 changes: 17 additions & 0 deletions apis/theme/src/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import EventEmitter from 'node-event-emitter';
import { color as d3color } from 'd3-color';

import setTheme from './set-theme';
import paletteResolverFn from './palette-resolver';
Expand Down Expand Up @@ -99,6 +100,22 @@ export default function theme() {

return styleResolverInstanceCache[basePath].getStyle(path, attribute);
},
/**
* Validates a color string using d3-color.
* See https://www.npmjs.com/package/d3-color
* @param {string} specifier
* @returns {string|undefined} The resolved color or undefined
* @ignore
*
* @example
* theme.validateColor("red"); // returns "rgba(255,0,0,1)"
* theme.validateColor("#00ff00"); // returns "rgba(0,255,0,1)"
* theme.validateColor("FOO"); // returns undefined
*/
validateColor(...args) {
const c = d3color(...args);
return c ? c.toString() : undefined;
},
};

const internalAPI = {
Expand Down

0 comments on commit 520f053

Please sign in to comment.