mirror of
https://github.com/wanderer-industries/wanderer
synced 2025-12-12 02:35:42 +00:00
@@ -28,6 +28,12 @@ body {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
#bg-canvas {
|
||||
position: absolute;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.ccp-font {
|
||||
font-family: 'Shentox', 'Rogan', sans-serif !important;
|
||||
}
|
||||
|
||||
@@ -48,6 +48,8 @@ export const SystemSignaturesContent = ({ systemId, settings }: SystemSignatures
|
||||
const [signatures, setSignatures, signaturesRef] = useRefState<SystemSignature[]>([]);
|
||||
const [selectedSignatures, setSelectedSignatures] = useState<SystemSignature[]>([]);
|
||||
const [nameColumnWidth, setNameColumnWidth] = useState('auto');
|
||||
const [parsedSignatures, setParsedSignatures] = useState<SystemSignature[]>([]);
|
||||
const [askUser, setAskUser] = useState(false);
|
||||
|
||||
const [hoveredSig, setHoveredSig] = useState<SystemSignature | null>(null);
|
||||
|
||||
@@ -90,8 +92,8 @@ export const SystemSignaturesContent = ({ systemId, settings }: SystemSignatures
|
||||
}, [outCommand, systemId]);
|
||||
|
||||
const handleUpdateSignatures = useCallback(
|
||||
async (newSignatures: SystemSignature[]) => {
|
||||
const { added, updated, removed } = getActualSigs(signaturesRef.current, newSignatures);
|
||||
async (newSignatures: SystemSignature[], updateOnly: boolean) => {
|
||||
const { added, updated, removed } = getActualSigs(signaturesRef.current, newSignatures, updateOnly);
|
||||
|
||||
const { signatures: updatedSignatures } = await outCommand({
|
||||
type: OutCommand.updateSignatures,
|
||||
@@ -114,13 +116,26 @@ export const SystemSignaturesContent = ({ systemId, settings }: SystemSignatures
|
||||
return;
|
||||
}
|
||||
const selectedSignaturesEveIds = selectedSignatures.map(x => x.eve_id);
|
||||
await handleUpdateSignatures(signatures.filter(x => !selectedSignaturesEveIds.includes(x.eve_id)));
|
||||
await handleUpdateSignatures(
|
||||
signatures.filter(x => !selectedSignaturesEveIds.includes(x.eve_id)),
|
||||
false,
|
||||
);
|
||||
}, [handleUpdateSignatures, signatures, selectedSignatures]);
|
||||
|
||||
const handleSelectAll = useCallback(() => {
|
||||
setSelectedSignatures(signatures);
|
||||
}, [signatures]);
|
||||
|
||||
const handleReplaceAll = useCallback(() => {
|
||||
handleUpdateSignatures(parsedSignatures, false);
|
||||
setAskUser(false);
|
||||
}, [parsedSignatures, handleUpdateSignatures]);
|
||||
|
||||
const handleUpdateOnly = useCallback(() => {
|
||||
handleUpdateSignatures(parsedSignatures, true);
|
||||
setAskUser(false);
|
||||
}, [parsedSignatures, handleUpdateSignatures]);
|
||||
|
||||
useHotkey(true, ['a'], handleSelectAll);
|
||||
|
||||
useHotkey(false, ['Backspace', 'Delete'], handleDeleteSelected);
|
||||
@@ -135,7 +150,12 @@ export const SystemSignaturesContent = ({ systemId, settings }: SystemSignatures
|
||||
settings.map(x => x.key),
|
||||
);
|
||||
|
||||
handleUpdateSignatures(signatures);
|
||||
if (!signaturesRef.current || !signaturesRef.current.length) {
|
||||
handleUpdateSignatures(signatures, false);
|
||||
} else {
|
||||
setParsedSignatures(signatures);
|
||||
setAskUser(true);
|
||||
}
|
||||
}, [clipboardContent]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -184,98 +204,125 @@ export const SystemSignaturesContent = ({ systemId, settings }: SystemSignatures
|
||||
// };
|
||||
|
||||
return (
|
||||
<div ref={tableRef} className="h-full">
|
||||
{filteredSignatures.length === 0 ? (
|
||||
<div className="w-full h-full flex justify-center items-center select-none text-stone-400/80 text-sm">
|
||||
No signatures
|
||||
<>
|
||||
{askUser && (
|
||||
<div className="flex w-full h-full bg-stone-900/95 backdrop-blur-sm">
|
||||
<div className="absolute top-0 left-0 w-full h-full flex flex-col items-center justify-center">
|
||||
<div className="text-stone-400/80 text-sm">
|
||||
<div className="flex flex-col text-center gap-2">
|
||||
<button className="p-button p-component p-button-outlined p-button-sm btn-wide">
|
||||
<span className="p-button-label p-c" onClick={handleReplaceAll}>
|
||||
Replace
|
||||
</span>
|
||||
</button>
|
||||
<button className="p-button p-component p-button-outlined p-button-sm btn-wide">
|
||||
<span className="p-button-label p-c" onClick={handleUpdateOnly}>
|
||||
Update
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<DataTable
|
||||
className={classes.Table}
|
||||
value={filteredSignatures}
|
||||
size="small"
|
||||
selectionMode="multiple"
|
||||
selection={selectedSignatures}
|
||||
metaKeySelection
|
||||
onSelectionChange={e => setSelectedSignatures(e.value)}
|
||||
dataKey="eve_id"
|
||||
tableClassName="w-full select-none"
|
||||
resizableColumns={false}
|
||||
rowHover
|
||||
selectAll
|
||||
sortField={sortSettings.sortField}
|
||||
sortOrder={sortSettings.sortOrder}
|
||||
onSort={event => setSortSettings(() => ({ sortField: event.sortField, sortOrder: event.sortOrder }))}
|
||||
onRowMouseEnter={compact || medium ? handleEnterRow : undefined}
|
||||
onRowMouseLeave={compact || medium ? handleLeaveRow : undefined}
|
||||
rowClassName={row => {
|
||||
if (selectedSignatures.some(x => x.eve_id === row.eve_id)) {
|
||||
return clsx(classes.TableRowCompact, 'bg-amber-500/50 hover:bg-amber-500/70 transition duration-200');
|
||||
}
|
||||
|
||||
const dateClass = getRowColorByTimeLeft(row.updated_at ? new Date(row.updated_at) : undefined);
|
||||
if (!dateClass) {
|
||||
return clsx(classes.TableRowCompact, 'hover:bg-purple-400/20 transition duration-200');
|
||||
}
|
||||
|
||||
return clsx(classes.TableRowCompact, dateClass);
|
||||
}}
|
||||
>
|
||||
<Column
|
||||
bodyClassName="p-0 px-1"
|
||||
field="group"
|
||||
body={renderIcon}
|
||||
style={{ maxWidth: 26, minWidth: 26, width: 26, height: 25 }}
|
||||
></Column>
|
||||
|
||||
<Column
|
||||
field="eve_id"
|
||||
header="Id"
|
||||
bodyClassName="text-ellipsis overflow-hidden whitespace-nowrap"
|
||||
style={{ maxWidth: 72, minWidth: 72, width: 72 }}
|
||||
sortable
|
||||
></Column>
|
||||
<Column
|
||||
field="group"
|
||||
header="Group"
|
||||
bodyClassName="text-ellipsis overflow-hidden whitespace-nowrap"
|
||||
hidden={compact}
|
||||
sortable
|
||||
></Column>
|
||||
<Column
|
||||
field="name"
|
||||
header="Name"
|
||||
bodyClassName="text-ellipsis overflow-hidden whitespace-nowrap"
|
||||
body={renderName}
|
||||
style={{ maxWidth: nameColumnWidth }}
|
||||
hidden={compact || medium}
|
||||
sortable
|
||||
></Column>
|
||||
<Column
|
||||
field="updated_at"
|
||||
header="Updated"
|
||||
dataType="date"
|
||||
bodyClassName="w-[80px] text-ellipsis overflow-hidden whitespace-nowrap"
|
||||
body={renderTimeLeft}
|
||||
sortable
|
||||
></Column>
|
||||
|
||||
{/*<Column*/}
|
||||
{/* bodyClassName="p-0 pl-1 pr-2"*/}
|
||||
{/* field="group"*/}
|
||||
{/* body={renderToolbar}*/}
|
||||
{/* headerClassName={headerClasses}*/}
|
||||
{/* style={{ maxWidth: 26, minWidth: 26, width: 26 }}*/}
|
||||
{/*></Column>*/}
|
||||
</DataTable>
|
||||
</>
|
||||
)}
|
||||
<WdTooltip
|
||||
className="bg-stone-900/95 text-slate-50"
|
||||
ref={tooltipRef}
|
||||
content={hoveredSig ? <SignatureView {...hoveredSig} /> : null}
|
||||
/>
|
||||
</div>
|
||||
{!askUser && (
|
||||
<div ref={tableRef} className="h-full">
|
||||
{filteredSignatures.length === 0 ? (
|
||||
<div className="w-full h-full flex justify-center items-center select-none text-stone-400/80 text-sm">
|
||||
No signatures
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<DataTable
|
||||
className={classes.Table}
|
||||
value={filteredSignatures}
|
||||
size="small"
|
||||
selectionMode="multiple"
|
||||
selection={selectedSignatures}
|
||||
metaKeySelection
|
||||
onSelectionChange={e => setSelectedSignatures(e.value)}
|
||||
dataKey="eve_id"
|
||||
tableClassName="w-full select-none"
|
||||
resizableColumns={false}
|
||||
rowHover
|
||||
selectAll
|
||||
sortField={sortSettings.sortField}
|
||||
sortOrder={sortSettings.sortOrder}
|
||||
onSort={event => setSortSettings(() => ({ sortField: event.sortField, sortOrder: event.sortOrder }))}
|
||||
onRowMouseEnter={compact || medium ? handleEnterRow : undefined}
|
||||
onRowMouseLeave={compact || medium ? handleLeaveRow : undefined}
|
||||
rowClassName={row => {
|
||||
if (selectedSignatures.some(x => x.eve_id === row.eve_id)) {
|
||||
return clsx(
|
||||
classes.TableRowCompact,
|
||||
'bg-amber-500/50 hover:bg-amber-500/70 transition duration-200',
|
||||
);
|
||||
}
|
||||
|
||||
const dateClass = getRowColorByTimeLeft(row.updated_at ? new Date(row.updated_at) : undefined);
|
||||
if (!dateClass) {
|
||||
return clsx(classes.TableRowCompact, 'hover:bg-purple-400/20 transition duration-200');
|
||||
}
|
||||
|
||||
return clsx(classes.TableRowCompact, dateClass);
|
||||
}}
|
||||
>
|
||||
<Column
|
||||
bodyClassName="p-0 px-1"
|
||||
field="group"
|
||||
body={renderIcon}
|
||||
style={{ maxWidth: 26, minWidth: 26, width: 26, height: 25 }}
|
||||
></Column>
|
||||
|
||||
<Column
|
||||
field="eve_id"
|
||||
header="Id"
|
||||
bodyClassName="text-ellipsis overflow-hidden whitespace-nowrap"
|
||||
style={{ maxWidth: 72, minWidth: 72, width: 72 }}
|
||||
sortable
|
||||
></Column>
|
||||
<Column
|
||||
field="group"
|
||||
header="Group"
|
||||
bodyClassName="text-ellipsis overflow-hidden whitespace-nowrap"
|
||||
hidden={compact}
|
||||
sortable
|
||||
></Column>
|
||||
<Column
|
||||
field="name"
|
||||
header="Name"
|
||||
bodyClassName="text-ellipsis overflow-hidden whitespace-nowrap"
|
||||
body={renderName}
|
||||
style={{ maxWidth: nameColumnWidth }}
|
||||
hidden={compact || medium}
|
||||
sortable
|
||||
></Column>
|
||||
<Column
|
||||
field="updated_at"
|
||||
header="Updated"
|
||||
dataType="date"
|
||||
bodyClassName="w-[80px] text-ellipsis overflow-hidden whitespace-nowrap"
|
||||
body={renderTimeLeft}
|
||||
sortable
|
||||
></Column>
|
||||
|
||||
{/*<Column*/}
|
||||
{/* bodyClassName="p-0 pl-1 pr-2"*/}
|
||||
{/* field="group"*/}
|
||||
{/* body={renderToolbar}*/}
|
||||
{/* headerClassName={headerClasses}*/}
|
||||
{/* style={{ maxWidth: 26, minWidth: 26, width: 26 }}*/}
|
||||
{/*></Column>*/}
|
||||
</DataTable>
|
||||
</>
|
||||
)}
|
||||
<WdTooltip
|
||||
className="bg-stone-900/95 text-slate-50"
|
||||
ref={tooltipRef}
|
||||
content={hoveredSig ? <SignatureView {...hoveredSig} /> : null}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@ import { getState } from './getState.ts';
|
||||
export const getActualSigs = (
|
||||
oldSignatures: SystemSignature[],
|
||||
newSignatures: SystemSignature[],
|
||||
updateOnly: boolean,
|
||||
): { added: SystemSignature[]; updated: SystemSignature[]; removed: SystemSignature[] } => {
|
||||
const updated: SystemSignature[] = [];
|
||||
const removed: SystemSignature[] = [];
|
||||
@@ -20,7 +21,9 @@ export const getActualSigs = (
|
||||
updated.push({ ...oldSig, group: newSig.group, name: newSig.name });
|
||||
}
|
||||
} else {
|
||||
removed.push(oldSig);
|
||||
if (!updateOnly) {
|
||||
removed.push(oldSig);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -7,9 +7,9 @@ export const getState = (_: string[], newSig: SystemSignature) => {
|
||||
let state = -1;
|
||||
if (!newSig.group || newSig.group === '') {
|
||||
state = 0;
|
||||
} else if (!!newSig.group && newSig.group !== '' && newSig.name === '') {
|
||||
} else if (!newSig.name || newSig.name === '') {
|
||||
state = 1;
|
||||
} else if (!!newSig.group && newSig.group !== '' && newSig.name !== '') {
|
||||
} else if (newSig.name !== '') {
|
||||
state = 2;
|
||||
}
|
||||
return state;
|
||||
|
||||
@@ -3,7 +3,230 @@ import 'phoenix_html';
|
||||
|
||||
import './live_reload.css';
|
||||
|
||||
const animateBg = function (bgCanvas) {
|
||||
const { TweenMax, _ } = window;
|
||||
/**
|
||||
* Utility function for returning a random integer in a given range
|
||||
* @param {Int} max
|
||||
* @param {Int} min
|
||||
*/
|
||||
const randomInRange = (max, min) => Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
const BASE_SIZE = 1;
|
||||
const VELOCITY_INC = 1.01;
|
||||
const VELOCITY_INIT_INC = 0.525;
|
||||
const JUMP_VELOCITY_INC = 0.55;
|
||||
const JUMP_SIZE_INC = 1.15;
|
||||
const SIZE_INC = 1.01;
|
||||
const RAD = Math.PI / 180;
|
||||
const WARP_COLORS = [
|
||||
[197, 239, 247],
|
||||
[25, 181, 254],
|
||||
[77, 5, 232],
|
||||
[165, 55, 253],
|
||||
[255, 255, 255],
|
||||
];
|
||||
/**
|
||||
* Class for storing the particle metadata
|
||||
* position, size, length, speed etc.
|
||||
*/
|
||||
class Star {
|
||||
STATE = {
|
||||
alpha: Math.random(),
|
||||
angle: randomInRange(0, 360) * RAD,
|
||||
};
|
||||
reset = () => {
|
||||
const angle = randomInRange(0, 360) * (Math.PI / 180);
|
||||
const vX = Math.cos(angle);
|
||||
const vY = Math.sin(angle);
|
||||
const travelled =
|
||||
Math.random() > 0.5
|
||||
? Math.random() * Math.max(window.innerWidth, window.innerHeight) + Math.random() * (window.innerWidth * 0.24)
|
||||
: Math.random() * (window.innerWidth * 0.25);
|
||||
this.STATE = {
|
||||
...this.STATE,
|
||||
iX: undefined,
|
||||
iY: undefined,
|
||||
active: travelled ? true : false,
|
||||
x: Math.floor(vX * travelled) + window.innerWidth / 2,
|
||||
vX,
|
||||
y: Math.floor(vY * travelled) + window.innerHeight / 2,
|
||||
vY,
|
||||
size: BASE_SIZE,
|
||||
};
|
||||
};
|
||||
constructor() {
|
||||
this.reset();
|
||||
}
|
||||
}
|
||||
|
||||
const generateStarPool = size => new Array(size).fill().map(() => new Star());
|
||||
|
||||
// Class for the actual app
|
||||
// Not too much happens in here
|
||||
// Initiate the drawing process and listen for user interactions 👍
|
||||
class JumpToHyperspace {
|
||||
STATE = {
|
||||
stars: generateStarPool(300),
|
||||
bgAlpha: 0,
|
||||
sizeInc: SIZE_INC,
|
||||
velocity: VELOCITY_INC,
|
||||
};
|
||||
canvas = null;
|
||||
context = null;
|
||||
constructor(canvas) {
|
||||
this.canvas = canvas;
|
||||
this.context = canvas.getContext('2d');
|
||||
this.bind();
|
||||
this.setup();
|
||||
this.render();
|
||||
}
|
||||
render = () => {
|
||||
const {
|
||||
STATE: { bgAlpha, velocity, sizeInc, initiating, jumping, stars },
|
||||
context,
|
||||
render,
|
||||
} = this;
|
||||
// Clear the canvas
|
||||
context.clearRect(0, 0, window.innerWidth, window.innerHeight);
|
||||
if (bgAlpha > 0) {
|
||||
context.fillStyle = `rgba(31, 58, 157, ${bgAlpha})`;
|
||||
context.fillRect(0, 0, window.innerWidth, window.innerHeight);
|
||||
}
|
||||
// 1. Shall we add a new star
|
||||
const nonActive = stars.filter(s => !s.STATE.active);
|
||||
if (!initiating && nonActive.length > 0) {
|
||||
// Introduce a star
|
||||
nonActive[0].STATE.active = true;
|
||||
}
|
||||
// 2. Update the stars and draw them.
|
||||
for (const star of stars.filter(s => s.STATE.active)) {
|
||||
const { active, x, y, iX, iY, iVX, iVY, size, vX, vY } = star.STATE;
|
||||
// Check if the star needs deactivating
|
||||
if (
|
||||
((iX || x) < 0 || (iX || x) > window.innerWidth || (iY || y) < 0 || (iY || y) > window.innerHeight) &&
|
||||
active &&
|
||||
!initiating
|
||||
) {
|
||||
star.reset(true);
|
||||
} else if (active) {
|
||||
const newIX = initiating ? iX : iX + iVX;
|
||||
const newIY = initiating ? iY : iY + iVY;
|
||||
const newX = x + vX;
|
||||
const newY = y + vY;
|
||||
// Just need to work out if it overtakes the original line that's all
|
||||
const caught =
|
||||
(vX < 0 && newIX < x) || (vX > 0 && newIX > x) || (vY < 0 && newIY < y) || (vY > 0 && newIY > y);
|
||||
star.STATE = {
|
||||
...star.STATE,
|
||||
iX: caught ? undefined : newIX,
|
||||
iY: caught ? undefined : newIY,
|
||||
iVX: caught ? undefined : iVX * VELOCITY_INIT_INC,
|
||||
iVY: caught ? undefined : iVY * VELOCITY_INIT_INC,
|
||||
x: newX,
|
||||
vX: star.STATE.vX * velocity,
|
||||
y: newY,
|
||||
vY: star.STATE.vY * velocity,
|
||||
size: initiating ? size : size * (iX || iY ? SIZE_INC : sizeInc),
|
||||
};
|
||||
let color = `rgba(255, 255, 255, ${star.STATE.alpha})`;
|
||||
if (jumping) {
|
||||
const [r, g, b] = WARP_COLORS[randomInRange(0, WARP_COLORS.length)];
|
||||
color = `rgba(${r}, ${g}, ${b}, ${star.STATE.alpha})`;
|
||||
}
|
||||
context.strokeStyle = color;
|
||||
context.lineWidth = size;
|
||||
context.beginPath();
|
||||
context.moveTo(star.STATE.iX || x, star.STATE.iY || y);
|
||||
context.lineTo(star.STATE.x, star.STATE.y);
|
||||
context.stroke();
|
||||
}
|
||||
}
|
||||
requestAnimationFrame(render);
|
||||
};
|
||||
initiate = () => {
|
||||
if (this.STATE.jumping || this.STATE.initiating) return;
|
||||
this.STATE = {
|
||||
...this.STATE,
|
||||
initiating: true,
|
||||
initiateTimestamp: new Date().getTime(),
|
||||
};
|
||||
TweenMax.to(this.STATE, 0.25, { velocity: VELOCITY_INIT_INC, bgAlpha: 0.3 });
|
||||
// When we initiate, stop the XY origin from moving so that we draw
|
||||
// longer lines until the jump
|
||||
for (const star of this.STATE.stars.filter(s => s.STATE.active)) {
|
||||
star.STATE = {
|
||||
...star.STATE,
|
||||
iX: star.STATE.x,
|
||||
iY: star.STATE.y,
|
||||
iVX: star.STATE.vX,
|
||||
iVY: star.STATE.vY,
|
||||
};
|
||||
}
|
||||
};
|
||||
jump = () => {
|
||||
this.STATE = {
|
||||
...this.STATE,
|
||||
bgAlpha: 0,
|
||||
jumping: true,
|
||||
};
|
||||
TweenMax.to(this.STATE, 0.25, { velocity: JUMP_VELOCITY_INC, bgAlpha: 0.75, sizeInc: JUMP_SIZE_INC });
|
||||
setTimeout(() => {
|
||||
this.STATE = {
|
||||
...this.STATE,
|
||||
jumping: false,
|
||||
};
|
||||
TweenMax.to(this.STATE, 0.25, { bgAlpha: 0, velocity: VELOCITY_INC, sizeInc: SIZE_INC });
|
||||
}, 5000);
|
||||
};
|
||||
enter = () => {
|
||||
if (this.STATE.jumping) return;
|
||||
const { initiateTimestamp } = this.STATE;
|
||||
this.STATE = {
|
||||
...this.STATE,
|
||||
initiating: false,
|
||||
initiateTimestamp: undefined,
|
||||
};
|
||||
if (new Date().getTime() - initiateTimestamp > 600) {
|
||||
this.jump();
|
||||
} else {
|
||||
TweenMax.to(this.STATE, 0.25, { velocity: VELOCITY_INC, bgAlpha: 0 });
|
||||
}
|
||||
};
|
||||
bind = () => {
|
||||
this.canvas.addEventListener('mousedown', this.initiate);
|
||||
this.canvas.addEventListener('touchstart', this.initiate);
|
||||
this.canvas.addEventListener('mouseup', this.enter);
|
||||
this.canvas.addEventListener('touchend', this.enter);
|
||||
};
|
||||
setup = () => {
|
||||
this.context.lineCap = 'round';
|
||||
this.canvas.height = window.innerHeight;
|
||||
this.canvas.width = window.innerWidth;
|
||||
};
|
||||
reset = () => {
|
||||
this.STATE = {
|
||||
...this.STATE,
|
||||
stars: generateStarPool(300),
|
||||
};
|
||||
this.setup();
|
||||
};
|
||||
}
|
||||
window.myJump = new JumpToHyperspace(bgCanvas);
|
||||
window.addEventListener(
|
||||
'resize',
|
||||
_.debounce(() => {
|
||||
window.myJump.reset();
|
||||
}, 250),
|
||||
);
|
||||
};
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
// animage background
|
||||
const canvas = document.getElementById('bg-canvas');
|
||||
if (canvas) {
|
||||
animateBg(canvas);
|
||||
}
|
||||
|
||||
// Select all buttons with the 'share-link' class
|
||||
const buttons = document.querySelectorAll('button.copy-link');
|
||||
|
||||
|
||||
@@ -43,6 +43,20 @@
|
||||
>
|
||||
</script>
|
||||
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.js"
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
>
|
||||
</script>
|
||||
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.min.js"
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
>
|
||||
</script>
|
||||
|
||||
<script defer phx-track-static type="module" src={~p"/assets/app.js"} crossorigin="anonymous">
|
||||
</script>
|
||||
<!-- Appzi: Capture Insightful Feedback -->
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<section class="prose prose-lg max-w-full w-full leading-normal tracking-normal text-indigo-400 bg-cover bg-fixed flex items-center justify-center">
|
||||
<canvas id="bg-canvas"></canvas>
|
||||
<div class="h-full w-full flex flex-col items-center">
|
||||
<!--Main-->
|
||||
<div class="artboard artboard-horizontal phone-3 pt-10 !h-40">
|
||||
@@ -11,9 +12,17 @@
|
||||
</div>
|
||||
<!--Right Col-->
|
||||
<div :if={@invite_token_valid} class="overflow-hidden">
|
||||
<.link navigate={~p"/auth/eve?invite=#{@invite_token}"}>
|
||||
<img src="https://web.ccpgamescdn.com/eveonlineassets/developers/eve-sso-login-black-large.png" />
|
||||
</.link>
|
||||
<div class="!z-100 relative group alert items-center fade-in-scale text-white w-[224px] h-[44px] rounded p-px overflow-hidden">
|
||||
<div class="group animate-rotate absolute inset-0 h-full w-full rounded-full bg-[conic-gradient(#0ea5e9_20deg,transparent_120deg)] group-hover:bg-[#0ea5e9]" />
|
||||
<div class="!bg-black rounded w-[220px] h-[40px] flex items-center justify-center relative z-20">
|
||||
<.link navigate={~p"/auth/eve?invite=#{@invite_token}"} class="opacity-100">
|
||||
<img
|
||||
src="https://web.ccpgamescdn.com/eveonlineassets/developers/eve-sso-login-black-large.png"
|
||||
class="w-[220px] h-[40px]"
|
||||
/>
|
||||
</.link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -319,11 +319,14 @@ defmodule WandererAppWeb.AccessListsLive do
|
||||
|
||||
@impl true
|
||||
def handle_info({:search, text}, socket) do
|
||||
first_character_id =
|
||||
socket.assigns.user_character_ids
|
||||
|
||||
active_character_id =
|
||||
socket.assigns.current_user.characters
|
||||
|> Enum.filter(fn character -> not is_nil(character.refresh_token) end)
|
||||
|> Enum.map(& &1.id)
|
||||
|> Enum.at(0)
|
||||
|
||||
{:ok, options} = search(first_character_id, text)
|
||||
{:ok, options} = search(active_character_id, text)
|
||||
|
||||
send_update(LiveSelect.Component, options: options, id: socket.assigns.member_search_id)
|
||||
{:noreply, socket |> assign(member_search_options: options)}
|
||||
|
||||
@@ -58,7 +58,8 @@ defmodule WandererAppWeb.Router do
|
||||
~w('unsafe-inline'),
|
||||
~w(https://unpkg.com),
|
||||
~w(https://w.appzi.io),
|
||||
~w(https://www.googletagmanager.com)
|
||||
~w(https://www.googletagmanager.com),
|
||||
~w(https://cdnjs.cloudflare.com)
|
||||
],
|
||||
style_src: @style_src,
|
||||
img_src: @img_src,
|
||||
|
||||
Reference in New Issue
Block a user