diff --git a/apps/admin/src/components/core/views/login/LoginLeftView.vue b/apps/admin/src/components/core/views/login/LoginLeftView.vue index fd5d7af..171b7c8 100644 --- a/apps/admin/src/components/core/views/login/LoginLeftView.vue +++ b/apps/admin/src/components/core/views/login/LoginLeftView.vue @@ -49,7 +49,7 @@ width: 100%; height: 100%; object-fit: cover; - opacity: 0.4; + // opacity: 0.4; pointer-events: none; } diff --git a/apps/mobile/android/app/build.gradle.kts b/apps/mobile/android/app/build.gradle.kts index 793a619..3957a6c 100644 --- a/apps/mobile/android/app/build.gradle.kts +++ b/apps/mobile/android/app/build.gradle.kts @@ -1,3 +1,4 @@ +import java.util.Properties plugins { id("com.android.application") // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. @@ -25,11 +26,26 @@ android { versionName = flutter.versionName } + // 正式签名(key.properties + photo-live-release.jks,均不入库): + // 缺失时回退 debug 签名(CI/他人克隆仓库仍可构建)。 + val keystoreProps = Properties().apply { + val f = rootProject.file("app/key.properties") + if (f.exists()) f.inputStream().use { load(it) } + } + buildTypes { release { - // TODO: Add your own signing config for the release build. - // Signing with the debug keys for now, so `flutter run --release` works. - signingConfig = signingConfigs.getByName("debug") + signingConfig = if (keystoreProps.getProperty("storeFile") != null) { + signingConfigs.create("release") { + storeFile = rootProject.file("app/" + keystoreProps.getProperty("storeFile")) + storePassword = keystoreProps.getProperty("storePassword") + keyAlias = keystoreProps.getProperty("keyAlias") + keyPassword = keystoreProps.getProperty("keyPassword") + } + } else { + // Signing with the debug keys(无正式签名配置的构建机回退)。 + signingConfigs.getByName("debug") + } // R8 混淆会破坏 WorkManager 反射初始化(NoSuchMethodException // WorkDatabase_Impl),ProGuard keep 规则见 proguard-rules.pro。 isMinifyEnabled = true diff --git a/apps/viewer/e2e/verify-mfix2.mjs b/apps/viewer/e2e/verify-mfix2.mjs new file mode 100644 index 0000000..d2c1c39 --- /dev/null +++ b/apps/viewer/e2e/verify-mfix2.mjs @@ -0,0 +1,48 @@ +import { createServer } from 'node:http'; +import { chromium } from '@playwright/test'; +const server = createServer((_q, res) => { + res.setHeader('content-type', 'text/html; charset=utf-8'); + res.end(` + `); +}); +await new Promise((r) => server.listen(3980, '127.0.0.1', r)); +const browser = await chromium.launch(); +const page = await browser.newPage({ viewport: { width: 1440, height: 900 } }); +await page.goto('http://127.0.0.1:3980'); +const frame = page.locator('iframe[src*="/embed/"][src*="v=2"]'); +await frame.waitFor({ timeout: 20000 }); +await page.waitForTimeout(3000); +const f = page.frames().find((fr) => fr.url().includes('v=2')); +const offset = async () => { + const t = await f.locator('.stream-track').evaluate((el) => el.style.transform); + return Number.parseFloat((/translateY\((-?[\d.]+)px\)/.exec(t) ?? ['0', '0'])[1]); +}; +const box = await frame.boundingBox(); +const cx = (box ? box.x : 0) + 90, cy = (box ? box.y : 0) + 150; +const scrolling = async (ms = 1000) => { const a = await offset(); await page.waitForTimeout(ms); return a !== (await offset()); }; + +console.log('1. baseline =', await scrolling()); + +// 窗内拖动后,鼠标移开再验证(窗内 up 后鼠标停在窗内属正常 hover 暂停) +await page.mouse.move(cx, cy); await page.mouse.down(); +await page.mouse.move(cx, cy + 40, { steps: 4 }); await page.mouse.up(); +await page.mouse.move(30, 30); await page.waitForTimeout(1500); +console.log('2. after in-frame drag (pointer away) =', await scrolling()); + +// 窗外释放 +await page.mouse.move(cx, cy); await page.mouse.down(); +await page.mouse.move(cx + 120, cy + 200, { steps: 4 }); await page.mouse.up(); +await page.waitForTimeout(3500); +console.log('3. after outside-release =', await scrolling()); + +// 长跑 20s +const s1 = await offset(); await page.waitForTimeout(20000); const s2 = await offset(); +console.log('4. 20s moved =', Math.abs(s2 - s1).toFixed(0), 'px'); + +// hover 语义仍正常 +await page.mouse.move(cx, cy); await page.waitForTimeout(800); +const h1 = await offset(); await page.waitForTimeout(800); const h2 = await offset(); +await page.mouse.move(30, 30); await page.waitForTimeout(1500); +const h3 = await offset(); await page.waitForTimeout(800); const h4 = await offset(); +console.log('5. hover pause =', h1 === h2, '; leave resume =', h3 !== h4); +server.close(); await browser.close();