Skip to content

๐Ÿ”€ :: (#122) - QR ์ธ์‹ ์‹คํŒจ ํ›„ ์นด๋ฉ”๋ผ ๋ณต๊ท€ ์‹œ ๊ฒ€์€ ํ™”๋ฉด์œผ๋กœ ๋‚จ๋˜ ๋ฌธ์ œ ์ˆ˜์ • - #131

Merged
aiden30015 merged 2 commits into
developfrom
fix/#122-qr-camera-restart
Aug 19, 2026

Conversation

@aiden30015

Copy link
Copy Markdown
Contributor

๐Ÿ’ก ๊ฐœ์š”

QR ์ธ์‹ ์‹คํŒจ ํ›„ "์นด๋ฉ”๋ผ๋กœ ๋Œ์•„๊ฐ€๊ธฐ"๋ฅผ ๋ˆ„๋ฅด๋ฉด ํ™”๋ฉด์ด ๊ฒ€๊ฒŒ ๋‚จ๊ณ  ๋‹ค์‹œ ์ธ์‹๋˜์ง€ ์•Š๋˜ ๋ฌธ์ œ๋ฅผ ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ”— ๊ด€๋ จ ์ด์Šˆ

Closes #122

๐Ÿ“ƒ ์ž‘์—…๋‚ด์šฉ

์›์ธ

_onDetect ๊ฐ€ ์Šค์บ”์„ ๊ฐ์ง€ํ•˜๋ฉด ์นด๋ฉ”๋ผ๋ฅผ ๋ฉˆ์ถ”๋Š”๋ฐ, ์ด๊ฑธ ๋‹ค์‹œ ์ผœ๋Š” ์ฝ”๋“œ๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

_controller.stop();
await ref.read(qrScanProvider.notifier).processScan(barcode.rawValue!);

_controller.start() ๋Š” ํŒŒ์ผ ์–ด๋””์—๋„ ์—†์—ˆ๊ณ , initState ์—์„œ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๋งŒ๋“ค ๋•Œ๋งŒ ์นด๋ฉ”๋ผ๊ฐ€ ๋Œ์•˜์Šต๋‹ˆ๋‹ค.

์‹คํŒจ ๊ฒฝ๋กœ๋งŒ ์ด๊ฑธ ๋ฐŸ์Šต๋‹ˆ๋‹ค.

  1. ์‹คํŒจ โ†’ ๋ฆฌ์Šค๋„ˆ๊ฐ€ await context.push('/qr/result/failure'). push๋ผ์„œ QrScanScreen ์€ ์‚ด์•„์žˆ์Šต๋‹ˆ๋‹ค.
  2. "์นด๋ฉ”๋ผ๋กœ ๋Œ์•„๊ฐ€๊ธฐ" โ†’ context.go(RoutePath.qr)
  3. go_router ๊ฐ€ /qr ์„ ๋‹ค์‹œ ๋งค์นญํ•˜๋Š”๋ฐ state.pageKey ๊ฐ€ ๊ฐ™์•„์„œ ๊ฐ™์€ ElementยทState ๊ฐ€ ์žฌ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
    initState ๊ฐ€ ๋‹ค์‹œ ๋Œ์ง€ ์•Š์œผ๋‹ˆ ์ปจํŠธ๋กค๋Ÿฌ๋Š” ๋ฉˆ์ถ˜ ๊ทธ๋Œ€๋กœ โ†’ ๊ฒ€์€ ํ™”๋ฉด

์„ฑ๊ณต ๊ฒฝ๋กœ๋Š” ๊ฒฐ๊ณผ ํ™”๋ฉด ๋ฒ„ํŠผ์ด context.go('/home') ์ด๋ผ QrScanScreen ์ด ์–ธ๋งˆ์šดํŠธ๋˜๊ณ ,
๋‹ค์Œ ์ง„์ž… ๋•Œ State ๊ฐ€ ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์ ธ์„œ ๋ฉ€์ฉกํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์‹คํŒจ ํ›„ ๋ณต๊ท€์—์„œ๋งŒ ์žฌํ˜„๋์Šต๋‹ˆ๋‹ค.

์ˆ˜์ •

1. ๊ฒฐ๊ณผ ํ™”๋ฉด์—์„œ ๋Œ์•„์˜ค๋ฉด ์นด๋ฉ”๋ผ ์žฌ๊ฐœ

await context.push(resultLocation);

// ๊ฒฐ๊ณผ ํ™”๋ฉด์ด ๋‹ซํžˆ๊ณ  ์ด ํ™”๋ฉด์œผ๋กœ ๋Œ์•„์˜จ ๊ฒฝ์šฐ์—๋งŒ ์—ฌ๊ธฐ์— ๋„๋‹ฌํ•œ๋‹ค.
if (!mounted) return;
await _controller.start();

DetectionSpeed.noDuplicates ์˜ lastScanned ๋Š” start() / stop() ์–‘์ชฝ์—์„œ ์ดˆ๊ธฐํ™”๋˜๋ฏ€๋กœ
(MobileScanner.kt:396,594) ๊ฐ™์€ QR ์„ ๋‹ค์‹œ ์ฐ์–ด๋„ ์ •์ƒ ์ธ์‹๋ฉ๋‹ˆ๋‹ค.

2. ๋ณต๊ท€๋ฅผ go ๋Œ€์‹  pop ์œผ๋กœ
go ๋Š” ์Šคํƒ ์ „์ฒด๋ฅผ /qr ํ•˜๋‚˜๋กœ ๊ต์ฒดํ•ด์„œ, ์Šค์บ” ํ™”๋ฉด ์•„๋ž˜์— ์žˆ๋˜ ๋ผ์šฐํŠธ๊ฐ€ ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค.
๊ทธ๋ž˜์„œ ๋ณต๊ท€ ํ›„ ๋‹ซ๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ๋„ ์›๋ž˜ ํ™”๋ฉด์œผ๋กœ ๋ชป ๋Œ์•„๊ฐ”์Šต๋‹ˆ๋‹ค.
๊ฒฐ๊ณผ ํ™”๋ฉด์— ๋”ฅ๋งํฌ๋กœ ๋ฐ”๋กœ ์ง„์ž…ํ•œ ๊ฒฝ์šฐ๋ฅผ ์œ„ํ•ด go ํด๋ฐฑ์€ ๋‚จ๊ฒผ์Šต๋‹ˆ๋‹ค.

3. ๋ถˆํ•„์š”ํ•œ context.pop() ์ œ๊ฑฐ
์„ฑ๊ณต/์‹คํŒจ๋กœ ๊ฐˆ๋ผ์ ธ ์žˆ๋˜ ๋ฆฌ์Šค๋„ˆ๋ฅผ ํ•˜๋‚˜๋กœ ํ•ฉ์ณค์Šต๋‹ˆ๋‹ค.
๊ธฐ์กด์—๋Š” await push(...) ๋’ค์— if (mounted) context.pop(); ์ด ์žˆ์–ด์„œ,
2๋ฒˆ ์ƒํ™ฉ์—์„œ ์Šคํƒ์— /qr ํ•˜๋‚˜๋งŒ ๋‚จ์€ ์ฑ„๋กœ pop ์ด ์‹คํ–‰๋์Šต๋‹ˆ๋‹ค.

๐Ÿ” ํ…Œ์ŠคํŠธ ๋ฐฉ๋ฒ•

  • flutter analyze โ†’ 0๊ฑด
  • flutter test โ†’ 142๊ฐœ ํ†ต๊ณผ (์‹ ๊ทœ 2๊ฐœ ํฌํ•จ)
  • ํšŒ๊ท€ ํ…Œ์ŠคํŠธ test/widget/qr_scan_return_to_camera_widget_test.dart ์ถ”๊ฐ€.
    ์ˆ˜์ • ์ „ ์ฝ”๋“œ๋กœ ๋˜๋Œ๋ฆฌ๋ฉด ์ฒซ ๋ฒˆ์งธ ์ผ€์ด์Šค๊ฐ€ ์‹คํŒจํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ๊ธฐ๊ธฐ ํ™•์ธ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์นด๋ฉ”๋ผ ์žฌ๊ฐœ๋Š” ์œ„์ ฏ ํ…Œ์ŠคํŠธ๋กœ ๊ฒ€์ฆํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
    • QR ์Šค์บ” โ†’ ์ž˜๋ชป๋œ QR ์ด๋‚˜ ์„œ๋ฒ„ ์˜ค๋ฅ˜๋กœ ์‹คํŒจ โ†’ "์นด๋ฉ”๋ผ๋กœ ๋Œ์•„๊ฐ€๊ธฐ"
      โ†’ ์นด๋ฉ”๋ผ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๊ฐ€ ๋‹ค์‹œ ๋ณด์ด๋Š”์ง€
    • ์ด์–ด์„œ ๊ฐ™์€ QR ์„ ๋‹ค์‹œ ์ฐ์–ด๋„ ์ธ์‹๋˜๋Š”์ง€ (noDuplicates ์˜ํ–ฅ ํ™•์ธ)
    • ๋ณต๊ท€ ํ›„ ์ขŒ์ธก ์ƒ๋‹จ ๋‹ซ๊ธฐ(X) ๋ฒ„ํŠผ์ด ์›๋ž˜ ํ™”๋ฉด์œผ๋กœ ๋Œ์•„๊ฐ€๋Š”์ง€
    • ์„ฑ๊ณต ๊ฒฝ๋กœ(์™ธ์ถœ ์‹œ์ž‘ / ๋ณต๊ท€ / ์ง€๊ฐ / ์™ธ์ถœ๋ถˆ๊ฐ€)๋Š” ๊ธฐ์กด๋Œ€๋กœ ํ™ˆ์œผ๋กœ ๊ฐ€๋Š”์ง€

๐Ÿ™‹โ€โ™‚๏ธ ์งˆ๋ฌธ์‚ฌํ•ญ

  • _onDetect ์˜ _controller.stop() ์€ await ์—†์ด ํ˜ธ์ถœ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
    ์ด๋ฒˆ ์ˆ˜์ • ๋ฒ”์œ„์—์„œ๋Š” ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š์•˜๋Š”๋ฐ, ํ•จ๊ป˜ ์ •๋ฆฌํ• ์ง€ ์˜๊ฒฌ ์ฃผ์„ธ์š”.

โœ… ์ฒดํฌ๋ฆฌ์ŠคํŠธ

  • ์ฝ”๋“œ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์ปดํŒŒ์ผ๋˜๊ณ  ์‹คํ–‰๋˜๋Š”์ง€ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ๋ถˆํ•„์š”ํ•œ ์ฝ”๋“œ๊ฐ€ ์—†๋Š”์ง€ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ์ฝ”๋“œ ์Šคํƒ€์ผ ๊ฐ€์ด๋“œ๋ฅผ ์ค€์ˆ˜ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ๊ธฐ์กด ๊ธฐ๋Šฅ์ด ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค. (์นด๋ฉ”๋ผ ๋™์ž‘์€ ๊ธฐ๊ธฐ ํ™•์ธ ํ•„์š”)

๐Ÿค– Generated with Claude Code

_onDetect์—์„œ _controller.stop()์„ ๋ถ€๋ฅธ ๋’ค ๋‹ค์‹œ ์ผœ๋Š” ์ฝ”๋“œ๊ฐ€ ์—†์—ˆ๋‹ค.
์‹คํŒจ ๊ฒฐ๊ณผ ํ™”๋ฉด์˜ "์นด๋ฉ”๋ผ๋กœ ๋Œ์•„๊ฐ€๊ธฐ"๊ฐ€ context.go(RoutePath.qr)๋ผ
go_router๊ฐ€ ๊ฐ™์€ pageKey๋กœ /qr์„ ์žฌ๋งค์นญํ•˜๋ฉฐ ๊ธฐ์กด State๋ฅผ ์žฌ์‚ฌ์šฉํ–ˆ๊ณ ,
initState๊ฐ€ ๋‹ค์‹œ ๋Œ์ง€ ์•Š์•„ ๋ฉˆ์ถ˜ ์นด๋ฉ”๋ผ๊ฐ€ ๊ทธ๋Œ€๋กœ ๋‚จ์•˜๋‹ค.

- ๊ฒฐ๊ณผ ํ™”๋ฉด์ด ๋‹ซํžˆ๊ณ  ์Šค์บ” ํ™”๋ฉด์œผ๋กœ ๋Œ์•„์˜ค๋ฉด _controller.start()๋กœ ์žฌ๊ฐœ.
  lastScanned๋Š” start/stop ์–‘์ชฝ์—์„œ ์ดˆ๊ธฐํ™”๋˜๋ฏ€๋กœ ๊ฐ™์€ QR๋„ ๋‹ค์‹œ ์ฝํžŒ๋‹ค.
- ๋ณต๊ท€๋Š” go ๋Œ€์‹  pop. ์Šค์บ” ํ™”๋ฉด ์•„๋ž˜ ์Šคํƒ์ด ์‚ด์•„๋‚จ์•„ ๋‹ซ๊ธฐ ๋ฒ„ํŠผ๋„ ์ •์ƒ ๋™์ž‘ํ•œ๋‹ค.
  ๊ฒฐ๊ณผ ํ™”๋ฉด์— ๋ฐ”๋กœ ์ง„์ž…ํ•œ ๊ฒฝ์šฐ๋ฅผ ์œ„ํ•ด go ํด๋ฐฑ์€ ๋‚จ๊ฒผ๋‹ค.
- ์„ฑ๊ณต/์‹คํŒจ๋กœ ๊ฐˆ๋ผ์ ธ ์žˆ๋˜ ๋ฆฌ์Šค๋„ˆ๋ฅผ ํ•ฉ์น˜๋ฉด์„œ, go๋กœ ํ™ˆ์— ๊ฐ„ ๋’ค ์‹คํ–‰๋˜๋˜
  ๋ถˆํ•„์š”ํ•œ context.pop() ์ œ๊ฑฐ.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
buildQrScanResultScreen๊ณผ buildQrScanResultRouteScreen์ด ๋‚˜๋‰˜์–ด ์žˆ๊ณ ,
'failure' ๋งค์ง ์ŠคํŠธ๋ง ๋น„๊ต์™€ resultType == null ๊ฒ€์‚ฌ๊ฐ€ ๊ฐ๊ฐ
OutingFailedScreen์„ ๋ฐ˜ํ™˜ํ•ด ๊ฐ™์€ ์ฝ”๋“œ๊ฐ€ ๋‘ ๋ฒˆ ์žˆ์—ˆ๋‹ค.

- ๋‘ ํ•จ์ˆ˜๋ฅผ buildQrScanResultRouteScreen ํ•˜๋‚˜๋กœ ํ•ฉ์น˜๊ณ  switch ์‹์œผ๋กœ ์ •๋ฆฌ.
- 'failure'๋Š” QrScanResultType์˜ ์ด๋ฆ„๊ณผ ๊ฒน์น˜์ง€ ์•Š์œผ๋ฏ€๋กœ null ์ผ€์ด์Šค๋กœ
  ์ž์—ฐํžˆ ๋–จ์–ด์ง„๋‹ค. ๋งค์นญ๋˜์ง€ ์•Š๋Š” ๊ฐ’๋„ ๊ฐ™์€ ์ฒ˜๋ฆฌ๋ผ ๋™์ž‘์€ ๋™์ผํ•˜๋‹ค.
- ์„ฑ๊ณต์€ ํ™ˆ์œผ๋กœ, ์‹คํŒจ๋Š” ์Šค์บ” ํ™”๋ฉด์œผ๋กœ๋ผ๋Š” ๋ถ„๊ธฐ๊ฐ€ ํ•œ ์ž๋ฆฌ์— ๋ชจ์˜€๋‹ค.
- enum์— ๋ฉค๋ฒ„๊ฐ€ ๋Š˜๋ฉด non_exhaustive_switch_expression์œผ๋กœ ์žกํžŒ๋‹ค.
  ๊ธฐ์กด null ํด๋ฐฑ์€ ์กฐ์šฉํžˆ ์‹คํŒจ ํ™”๋ฉด์œผ๋กœ ๋„˜์–ด๊ฐ”๋‹ค.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@aiden30015
aiden30015 merged commit ff96b48 into develop Aug 19, 2026
1 check passed
@aiden30015 aiden30015 mentioned this pull request Aug 19, 2026
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant