Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(harbor): add modal content for copy result #130

Merged
merged 1 commit into from
Feb 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/page-spy-browser/src/assets/styles/modal.module.less
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,8 @@
gap: (8em / @font-size);
padding: (8em / @font-size) (14em / @font-size);
border-top: 1px solid #dedede;
button {
.common-button();
}
}
button {
.common-button();
}
}
16 changes: 16 additions & 0 deletions packages/page-spy-plugin-data-harbor/src/assets/index.module.less
Original file line number Diff line number Diff line change
Expand Up @@ -217,3 +217,19 @@
}
}
}

.result {
display: flex;
justify-content: center;
align-items: center;
gap: (12em / @font-size);
padding-block: (12em / @font-size);
svg {
width: (40em / @font-size);
height: (40em / @font-size);
color: var(--primary-color);
}
b {
font-size: (18em / @font-size);
}
}
8 changes: 4 additions & 4 deletions packages/page-spy-plugin-data-harbor/src/assets/locale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import { isCN } from '@huolala-tech/page-spy-base/dist/utils';
const source = {
zh: {
title: '离线日志',
uploadAll: '上传全量',
downloadAll: '下载全量',
uploadPeriods: '上传时间段',
downloadPeriods: '下载时间段',
readying: '准备数据...',
Expand All @@ -24,11 +22,11 @@ const source = {
eventCountNotEnough: '时间段内的数据量不足以回放',
invalidPeriods: '选择的开始时间无效',
invalidParams: '调用 onOfflineLog() 的参数不正确',
copyUrl: '复制调试链接',
copyFailed: '复制失败',
},
en: {
title: 'Offline log',
uploadAll: 'Upload All',
downloadAll: 'Download All',
uploadPeriods: 'Upload Periods',
downloadPeriods: 'Download Periods',
readying: 'Handling...',
Expand All @@ -49,6 +47,8 @@ const source = {
'The data within the time period is insufficient for playback',
invalidPeriods: 'The start of selected period is invalid',
invalidParams: 'Incorrect params which you call onOfflineLog()',
copyUrl: 'Copy URL',
copyFailed: 'Copy failed',
},
};

Expand Down
17 changes: 17 additions & 0 deletions packages/page-spy-plugin-data-harbor/src/assets/svg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,20 @@ export const refreshSvg = `
<path fill="currentColor" d="M3.5 12q0-3.616 2.664-6.058T12.5 3.5v-.692q0-.242.217-.354t.43.03l2.163 1.62q.323.242.323.646t-.323.646l-2.164 1.62q-.212.142-.429.03t-.217-.354V6Q9.86 6 7.93 7.718T6 12q0 .883.247 1.713t.73 1.556q.217.323.167.69t-.348.583l-.407.298q-.373.293-.818.227t-.711-.444q-.668-1.017-1.014-2.2Q3.5 13.241 3.5 12m8 8.5v.692q0 .243-.217.354q-.217.112-.43-.03l-2.162-1.62q-.324-.242-.324-.646t.323-.646l2.164-1.62q.212-.142.429-.03t.217.354V18q2.64 0 4.57-1.718T18 12q0-.883-.247-1.722q-.247-.84-.73-1.566q-.217-.323-.167-.69t.348-.583l.407-.298q.373-.293.818-.225t.712.442q.661 1.036 1.01 2.21T20.5 12q0 3.616-2.664 6.058T11.5 20.5"/>
</svg>
`;

export const successSvg = `
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24">
<path fill="currentColor" fill-rule="evenodd"
d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10s-4.477 10-10 10m-1.177-7.86l-2.765-2.767L7 12.431l3.119 3.121a1 1 0 0 0 1.414 0l5.952-5.95l-1.062-1.062z" />
</svg>
`;

export const copySvg = `
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24">
<g fill="none" stroke="white" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path
d="M7 9.667A2.667 2.667 0 0 1 9.667 7h8.666A2.667 2.667 0 0 1 21 9.667v8.666A2.667 2.667 0 0 1 18.333 21H9.667A2.667 2.667 0 0 1 7 18.333z" />
<path d="M4.012 16.737A2 2 0 0 1 3 15V5c0-1.1.9-2 2-2h10c.75 0 1.158.385 1.5 1" />
</g>
</svg>
`;
11 changes: 8 additions & 3 deletions packages/page-spy-plugin-data-harbor/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,15 @@ function fillTimeText(v: number) {
return `0${v}`;
}

export function formatTimeDuration(millsDiff: number) {
const seconds = parseInt(String(millsDiff / 1000), 10);
export function formatTime(seconds: number) {
const h = Math.floor(seconds / 3600);
const m = Math.floor((seconds - 3600 * h) / 60);
const s = Math.floor(seconds - 3600 * h - 60 * m);
return `${fillTimeText(h)}:${fillTimeText(m)}:${fillTimeText(s)}`;

const hh = fillTimeText(h);
const mm = fillTimeText(m);
const ss = fillTimeText(s);
if (h === 0) return `${mm}:${ss}`;

return `${hh}:${mm}:${ss}`;
}
112 changes: 40 additions & 72 deletions packages/page-spy-plugin-data-harbor/src/utils/modal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,17 @@ import copy from 'copy-to-clipboard';
import classes from '../assets/index.module.less';
import {
cropSvg,
downloadAllSvg,
uploadAllSvg,
uploadPeriodsSvg,
downloadPeriodsSvg,
refreshSvg,
successSvg,
copySvg,
} from '../assets/svg';
import { t } from '../assets/locale';
import { PeriodItem } from '../harbor/base';
import { formatTimeDuration } from './index';
import { formatTime } from './index';
import type DataHarborPlugin from '../index';

function getLocaleTime(v: number) {
return new Date(v).toLocaleTimeString('en', { hour12: false });
}

function gapBetweenTextOnThumb(max: number) {
if (max < 10) return 0.2;
if (max < 30) return 0.16;
Expand Down Expand Up @@ -68,22 +64,25 @@ export const buildModal = ({ plugin, modal, toast }: Params) => {
</div>

<!-- Upload / Download log button -->
<button class="page-spy-btn" data-primary id="upload-all">
${uploadAllSvg}
<span>${t.uploadAll}</span>
</button>
<button class="page-spy-btn" data-primary id="download-all">
${downloadAllSvg}
<span>${t.downloadAll}</span>
</button>
<button class="page-spy-btn" data-dashed id="upload-periods">
<button class="page-spy-btn" data-primary id="upload-periods">
${uploadPeriodsSvg}
<span>${t.uploadPeriods}</span>
</button>
<button class="page-spy-btn" data-dashed id="download-periods">
<button class="page-spy-btn" id="download-periods">
${downloadPeriodsSvg}
<span>${t.downloadPeriods}</span>
</button>

<!-- Result -->
<div class="${classes.result}">
${successSvg}
<b>${t.success}</b>
</div>

<button class="page-spy-btn" data-primary id="copy-replay-url" data-url>
${copySvg}
<span>${t.copyUrl}</span>
</button>
`,
'text/html',
);
Expand All @@ -100,10 +99,10 @@ export const buildModal = ({ plugin, modal, toast }: Params) => {
const minThumb = $('#period-min') as HTMLInputElement;
const maxThumb = $('#period-max') as HTMLInputElement;
const remark = $('#harbor-remark') as HTMLInputElement;
const uploadAllButton = $('#upload-all') as HTMLButtonElement;
const downloadAllButton = $('#download-all') as HTMLButtonElement;
const uploadPeriodsButton = $('#upload-periods') as HTMLButtonElement;
const downloadPeriodsButton = $('#download-periods') as HTMLButtonElement;
const resultContent = $c(classes.result) as HTMLDivElement;
const copyUrlButton = $('#copy-replay-url') as HTMLButtonElement;

const periodInfoRef: {
max: number;
Expand All @@ -117,7 +116,7 @@ export const buildModal = ({ plugin, modal, toast }: Params) => {
lastTime: 0,
};
const updateRangeInTrack = () => {
const { max, firstTime } = periodInfoRef;
const { max } = periodInfoRef;
const minValue = +minThumb.value;
const maxValue = +maxThumb.value;

Expand All @@ -126,10 +125,8 @@ export const buildModal = ({ plugin, modal, toast }: Params) => {
range.style.setProperty('--left', `${(left * 100).toFixed(3)}%`);
range.style.setProperty('--right', `${(right * 100).toFixed(3)}%`);

const leftTime = firstTime + minValue * 1000;
const rightTime = firstTime + maxValue * 1000;
range.style.setProperty('--min-text', `"${getLocaleTime(leftTime)}"`);
range.style.setProperty('--max-text', `"${getLocaleTime(rightTime)}"`);
range.style.setProperty('--min-text', `"${formatTime(minValue)}"`);
range.style.setProperty('--max-text', `"${formatTime(maxValue)}"`);
};

const refreshPeriods = () => {
Expand Down Expand Up @@ -206,38 +203,11 @@ export const buildModal = ({ plugin, modal, toast }: Params) => {
range.dataset.maxTextPosition = 'top';
updateRangeInTrack();
});
uploadAllButton.addEventListener('click', async () => {
try {
uploadAllButton.disabled = true;
const debugUrl = await plugin.onOfflineLog('upload', {
clearCache: false,
remark: remark.value,
});
const ok = copy(debugUrl);
psLog.info(`${t.success}: ${debugUrl}`);
toast.message(ok ? t.copied : t.success);
} catch (e: any) {
psLog.error(e);
toast.message(e.message);
} finally {
uploadAllButton.disabled = false;
}
});
downloadAllButton.addEventListener('click', async () => {
try {
downloadAllButton.disabled = true;
// await plugin.onOfflineLog('download', false);
await plugin.onOfflineLog('download', {
clearCache: false,
remark: remark.value,
});
toast.message(t.success);
} catch (e: any) {
psLog.error(e);
toast.message(e.message);
} finally {
downloadAllButton.disabled = false;
}
copyUrlButton.addEventListener('click', () => {
const { url } = copyUrlButton.dataset;
const ok = copy(url!);
toast.message(ok ? t.copied : t.copyFailed);
modal.close();
});
uploadPeriodsButton.addEventListener('click', async () => {
try {
Expand All @@ -247,9 +217,11 @@ export const buildModal = ({ plugin, modal, toast }: Params) => {
getSelectedPeriod(),
);

const ok = copy(debugUrl);
psLog.info(`${t.success}: ${debugUrl}`);
toast.message(ok ? t.copied : t.success);
copyUrlButton.dataset.url = debugUrl;
modal.show({
content: resultContent,
footer: [copyUrlButton],
});
} catch (e: any) {
psLog.error(e);
toast.message(e.message);
Expand All @@ -276,25 +248,21 @@ export const buildModal = ({ plugin, modal, toast }: Params) => {

const duration = modalContent?.querySelector(`.${classes.duration}`);
if (duration) {
duration.textContent = formatTimeDuration(
Date.now() - plugin.startTimestamp,
);
durationTimer = setInterval(() => {
duration.textContent = formatTimeDuration(
Date.now() - plugin.startTimestamp,
const fn = () => {
const seconds = parseInt(
String((Date.now() - plugin.startTimestamp) / 1000),
10,
);
}, 1000);
duration.textContent = formatTime(seconds);
};
fn();
durationTimer = setInterval(fn, 1000);
}
refreshPeriods();

modal.show({
content: modalContent,
footer: [
uploadAllButton,
uploadPeriodsButton,
downloadAllButton,
downloadPeriodsButton,
],
footer: [uploadPeriodsButton, downloadPeriodsButton],
});
});

Expand Down
Loading