From 8fe79aee6696bc27b3cbdd89680f25cfe5117943 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 30 Apr 2026 21:04:55 +0800 Subject: [PATCH] chore(deps): update github actions (#6861) * fix(ui): reduce idle traffic graph redraws * fix(sysproxy): preserve global proxy apply order #6760, #6832, #6790, #6793, #6801 * chore(deps): update github actions --------- Co-authored-by: Tunglies <77394545+Tunglies@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/autobuild.yml | 10 +- .github/workflows/copilot-setup-steps.yml | 2 +- .github/workflows/pr-ai-slop-review.lock.yml | 10 +- src/components/layout/traffic-graph.tsx | 253 +++++++++++-------- 4 files changed, 157 insertions(+), 118 deletions(-) diff --git a/.github/workflows/autobuild.yml b/.github/workflows/autobuild.yml index 7abd0366c..87dfb6e37 100644 --- a/.github/workflows/autobuild.yml +++ b/.github/workflows/autobuild.yml @@ -38,7 +38,7 @@ jobs: run: bash ./scripts/extract_update_logs.sh shell: bash - - uses: pnpm/action-setup@v6.0.1 + - uses: pnpm/action-setup@v6.0.3 name: Install pnpm with: run_install: false @@ -179,7 +179,7 @@ jobs: echo "OPENSSL_LIB_DIR=$(brew --prefix openssl@3)/lib" >> $GITHUB_ENV echo "PKG_CONFIG_PATH=$(brew --prefix openssl@3)/lib/pkgconfig" >> $GITHUB_ENV - - uses: pnpm/action-setup@v6.0.1 + - uses: pnpm/action-setup@v6.0.3 name: Install pnpm with: run_install: false @@ -278,7 +278,7 @@ jobs: cache-workspace-crates: true - name: Install pnpm - uses: pnpm/action-setup@v6.0.1 + uses: pnpm/action-setup@v6.0.3 with: run_install: false @@ -423,7 +423,7 @@ jobs: cache-workspace-crates: true - name: Install pnpm - uses: pnpm/action-setup@v6.0.1 + uses: pnpm/action-setup@v6.0.3 with: run_install: false @@ -534,7 +534,7 @@ jobs: with: node-version: '24.15.0' - - uses: pnpm/action-setup@v6.0.1 + - uses: pnpm/action-setup@v6.0.3 name: Install pnpm with: run_install: false diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index 04ec0c32a..8b2ddb6cb 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -21,6 +21,6 @@ jobs: - name: Checkout repository uses: actions/checkout@v6 - name: Install gh-aw extension - uses: github/gh-aw-actions/setup-cli@f52802884d655622f0a2dfd6d6a2250983c95523 # v0.68.7 + uses: github/gh-aw-actions/setup-cli@ab8940d1df237fc4fae4ab8091e7ba66ada55a55 # v0.71.2 with: version: v0.68.1 diff --git a/.github/workflows/pr-ai-slop-review.lock.yml b/.github/workflows/pr-ai-slop-review.lock.yml index 14bd11c8e..4dcfb22a5 100644 --- a/.github/workflows/pr-ai-slop-review.lock.yml +++ b/.github/workflows/pr-ai-slop-review.lock.yml @@ -83,7 +83,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@f52802884d655622f0a2dfd6d6a2250983c95523 # v0.68.7 + uses: github/gh-aw-actions/setup@ab8940d1df237fc4fae4ab8091e7ba66ada55a55 # v0.71.2 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -311,7 +311,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@f52802884d655622f0a2dfd6d6a2250983c95523 # v0.68.7 + uses: github/gh-aw-actions/setup@ab8940d1df237fc4fae4ab8091e7ba66ada55a55 # v0.71.2 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -868,7 +868,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@f52802884d655622f0a2dfd6d6a2250983c95523 # v0.68.7 + uses: github/gh-aw-actions/setup@ab8940d1df237fc4fae4ab8091e7ba66ada55a55 # v0.71.2 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -974,7 +974,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@f52802884d655622f0a2dfd6d6a2250983c95523 # v0.68.7 + uses: github/gh-aw-actions/setup@ab8940d1df237fc4fae4ab8091e7ba66ada55a55 # v0.71.2 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1142,7 +1142,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@f52802884d655622f0a2dfd6d6a2250983c95523 # v0.68.7 + uses: github/gh-aw-actions/setup@ab8940d1df237fc4fae4ab8091e7ba66ada55a55 # v0.71.2 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} diff --git a/src/components/layout/traffic-graph.tsx b/src/components/layout/traffic-graph.tsx index 3752080ca..d732dd24c 100644 --- a/src/components/layout/traffic-graph.tsx +++ b/src/components/layout/traffic-graph.tsx @@ -12,9 +12,18 @@ const upLineWidth = 4 const downLineAlpha = 1 const downLineWidth = 4 +const sampleIntervalMs = 1000 const frameIntervalMs = 1000 / 15 +const animationDurationMs = sampleIntervalMs -const defaultList = Array(maxPoint + 2).fill({ up: 0, down: 0 }) +const zeroTraffic: Traffic = { up: 0, down: 0 } +const createDefaultList = () => + Array.from({ length: maxPoint + 2 }, () => ({ ...zeroTraffic })) + +const hasTraffic = (traffic?: Traffic | null) => + (traffic?.up ?? 0) !== 0 || (traffic?.down ?? 0) !== 0 + +const hasRetainedTraffic = (list: Traffic[]) => list.some(hasTraffic) export interface TrafficRef { appendData: (data: Traffic) => void @@ -29,10 +38,11 @@ type TrafficValueKey = 'up' | 'down' export function TrafficGraph({ ref }: { ref?: Ref }) { const countRef = useRef(0) const styleRef = useRef(true) - const listRef = useRef(defaultList) + const listRef = useRef(createDefaultList()) const canvasRef = useRef(null!) const cacheRef = useRef(null) + const requestDrawRef = useRef<(animate?: boolean) => void>(() => {}) const { palette } = useTheme() @@ -42,23 +52,28 @@ export function TrafficGraph({ ref }: { ref?: Ref }) { }, toggleStyle: () => { styleRef.current = !styleRef.current + requestDrawRef.current(false) }, })) useEffect(() => { - let timer: any - const zero = { up: 0, down: 0 } + let timer: ReturnType | null = null const handleData = () => { - const data = cacheRef.current ? cacheRef.current : zero + const data = cacheRef.current ?? zeroTraffic cacheRef.current = null const list = listRef.current - if (list.length > maxPoint + 2) list.shift() - list.push(data) - countRef.current = 0 + const shouldAppend = hasTraffic(data) || hasRetainedTraffic(list) - timer = setTimeout(handleData, 1000) + if (shouldAppend) { + if (list.length > maxPoint + 2) list.shift() + list.push(data) + countRef.current = 0 + requestDrawRef.current(true) + } + + timer = setTimeout(handleData, sampleIntervalMs) } handleData() @@ -71,6 +86,9 @@ export function TrafficGraph({ ref }: { ref?: Ref }) { useEffect(() => { let raf = 0 let frameTimer: ReturnType | null = null + let resizeObserver: ResizeObserver | null = null + let animationStart = 0 + let lastFrameTime = 0 const canvas = canvasRef.current! if (!canvas) return @@ -84,104 +102,75 @@ export function TrafficGraph({ ref }: { ref?: Ref }) { const upLineColor = secondary.main || '#9c27b0' const downLineColor = primary.main || '#5b5c9d' - const width = canvas.width - const height = canvas.height - const dx = width / maxPoint - const dy = height / 7 - const l1 = dy - const l2 = dy * 4 - - const countY = (v: number) => { - const h = height - - if (v == 0) return h - 1 - if (v <= 10) return h - (v / 10) * dy - if (v <= 100) return h - (v / 100 + 1) * dy - if (v <= 1024) return h - (v / 1024 + 2) * dy - if (v <= 10240) return h - (v / 10240 + 3) * dy - if (v <= 102400) return h - (v / 102400 + 4) * dy - if (v <= 1048576) return h - (v / 1048576 + 5) * dy - if (v <= 10485760) return h - (v / 10485760 + 6) * dy - return 1 - } - - const drawBezier = ( - list: Traffic[], - valueKey: TrafficValueKey, - offset: number, - ) => { - if (list.length === 0) return - - const firstX = (dx * -1 - offset + 3) | 0 - const firstY = countY(list[0]?.[valueKey] ?? 0) - - context.moveTo(firstX, firstY) - - for (let i = 1; i < list.length; i++) { - const p1x = (dx * (i - 1) - offset + 3) | 0 - const p1y = countY(list[i]?.[valueKey] ?? 0) - - const hasNext = i + 1 < list.length - const p2x = hasNext ? (dx * i - offset + 3) | 0 : p1x - const p2y = hasNext ? countY(list[i + 1]?.[valueKey] ?? 0) : p1y - - context.quadraticCurveTo(p1x, p1y, (p1x + p2x) / 2, (p1y + p2y) / 2) - } - } - - const drawLine = ( - list: Traffic[], - valueKey: TrafficValueKey, - offset: number, - ) => { - if (list.length === 0) return - - context.moveTo((dx * -1 - offset) | 0, countY(list[0]?.[valueKey] ?? 0)) - - for (let i = 1; i < list.length; i++) { - context.lineTo( - (dx * (i - 1) - offset) | 0, - countY(list[i]?.[valueKey] ?? 0), - ) - } - } - - const scheduleDraw = (lastTime: number, delay = 0) => { + const cancelPendingDraw = () => { if (frameTimer !== null) { clearTimeout(frameTimer) frameTimer = null } - if (delay > 0) { - frameTimer = setTimeout(() => { - frameTimer = null - raf = requestAnimationFrame(() => { - raf = 0 - drawGraph(lastTime) - }) - }, delay) - return - } - - raf = requestAnimationFrame(() => { + if (raf) { + cancelAnimationFrame(raf) raf = 0 - drawGraph(lastTime) - }) + } } - const drawGraph = (lastTime: number) => { + const drawGraph = (offset = countRef.current) => { const list = listRef.current const lineStyle = styleRef.current - const now = Date.now() - const diff = now - lastTime - if (diff < frameIntervalMs) { - scheduleDraw(lastTime, frameIntervalMs - diff) - return + const width = canvas.width + const height = canvas.height + const dx = width / maxPoint + const dy = height / 7 + const l1 = dy + const l2 = dy * 4 + + const countY = (v: number) => { + const h = height + + if (v == 0) return h - 1 + if (v <= 10) return h - (v / 10) * dy + if (v <= 100) return h - (v / 100 + 1) * dy + if (v <= 1024) return h - (v / 1024 + 2) * dy + if (v <= 10240) return h - (v / 10240 + 3) * dy + if (v <= 102400) return h - (v / 102400 + 4) * dy + if (v <= 1048576) return h - (v / 1048576 + 5) * dy + if (v <= 10485760) return h - (v / 10485760 + 6) * dy + return 1 + } + + const drawBezier = (list: Traffic[], valueKey: TrafficValueKey) => { + if (list.length === 0) return + + const firstX = (dx * -1 - offset + 3) | 0 + const firstY = countY(list[0]?.[valueKey] ?? 0) + + context.moveTo(firstX, firstY) + + for (let i = 1; i < list.length; i++) { + const p1x = (dx * (i - 1) - offset + 3) | 0 + const p1y = countY(list[i]?.[valueKey] ?? 0) + + const hasNext = i + 1 < list.length + const p2x = hasNext ? (dx * i - offset + 3) | 0 : p1x + const p2y = hasNext ? countY(list[i + 1]?.[valueKey] ?? 0) : p1y + + context.quadraticCurveTo(p1x, p1y, (p1x + p2x) / 2, (p1y + p2y) / 2) + } + } + + const drawLine = (list: Traffic[], valueKey: TrafficValueKey) => { + if (list.length === 0) return + + context.moveTo((dx * -1 - offset) | 0, countY(list[0]?.[valueKey] ?? 0)) + + for (let i = 1; i < list.length; i++) { + context.lineTo( + (dx * (i - 1) - offset) | 0, + countY(list[i]?.[valueKey] ?? 0), + ) + } } - const temp = Math.min((diff / 1000) * dx + countRef.current, dx) - const offset = countRef.current === 0 ? 0 : temp - countRef.current = temp context.clearRect(0, 0, width, height) @@ -202,9 +191,9 @@ export function TrafficGraph({ ref }: { ref?: Ref }) { context.lineWidth = upLineWidth context.strokeStyle = upLineColor if (lineStyle) { - drawBezier(list, 'up', offset) + drawBezier(list, 'up') } else { - drawLine(list, 'up', offset) + drawLine(list, 'up') } context.stroke() context.closePath() @@ -214,25 +203,75 @@ export function TrafficGraph({ ref }: { ref?: Ref }) { context.lineWidth = downLineWidth context.strokeStyle = downLineColor if (lineStyle) { - drawBezier(list, 'down', offset) + drawBezier(list, 'down') } else { - drawLine(list, 'down', offset) + drawLine(list, 'down') } context.stroke() context.closePath() - - scheduleDraw(now, frameIntervalMs) } - drawGraph(Date.now() - frameIntervalMs) + const drawAnimatedFrame = (timestamp: number) => { + raf = 0 + + const timeSinceLastFrame = timestamp - lastFrameTime + if (timeSinceLastFrame < frameIntervalMs) { + frameTimer = setTimeout(() => { + frameTimer = null + raf = requestAnimationFrame(drawAnimatedFrame) + }, frameIntervalMs - timeSinceLastFrame) + return + } + + lastFrameTime = timestamp + + const dx = canvas.width / maxPoint + const progress = Math.min( + (timestamp - animationStart) / animationDurationMs, + 1, + ) + const offset = progress * dx + countRef.current = offset + drawGraph(offset) + + if (progress < 1) { + raf = requestAnimationFrame(drawAnimatedFrame) + return + } + + countRef.current = dx + } + + const requestDraw = (animate = false) => { + cancelPendingDraw() + + if (!animate) { + raf = requestAnimationFrame(() => { + raf = 0 + drawGraph() + }) + return + } + + animationStart = performance.now() + lastFrameTime = animationStart - frameIntervalMs + raf = requestAnimationFrame(drawAnimatedFrame) + } + + requestDrawRef.current = requestDraw + requestDraw(false) + + if (typeof ResizeObserver !== 'undefined') { + resizeObserver = new ResizeObserver(() => requestDraw(false)) + resizeObserver.observe(canvas) + } return () => { - if (frameTimer !== null) { - clearTimeout(frameTimer) - } - if (raf) { - cancelAnimationFrame(raf) + if (requestDrawRef.current === requestDraw) { + requestDrawRef.current = () => {} } + resizeObserver?.disconnect() + cancelPendingDraw() } }, [palette])