Skip to content

fix: restore working camera, fix PayPal donation link#10

Merged
BEKO2210 merged 1 commit intomainfrom
claude/restore-github-actions-workflow-oueZr
Mar 8, 2026
Merged

fix: restore working camera, fix PayPal donation link#10
BEKO2210 merged 1 commit intomainfrom
claude/restore-github-actions-workflow-oueZr

Conversation

@BEKO2210
Copy link
Copy Markdown
Owner

@BEKO2210 BEKO2210 commented Mar 8, 2026

  • Revert ImageCaptureModal to the original working version
  • Fix PayPal link: use paypal.com/donate with email parameter instead of broken paypal.me profile link

https://claude.ai/code/session_018567acDi8JQ3BHH8BxYX5b

- Revert ImageCaptureModal to the original working version
- Fix PayPal link: use paypal.com/donate with email parameter
  instead of broken paypal.me profile link

https://claude.ai/code/session_018567acDi8JQ3BHH8BxYX5b
@BEKO2210 BEKO2210 merged commit 9ab1c17 into main Mar 8, 2026
3 checks passed
@BEKO2210 BEKO2210 deleted the claude/restore-github-actions-workflow-oueZr branch March 8, 2026 16:23
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 959c1f156e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 40 to +43
streamRef.current = stream;

if (videoRef.current) {
videoRef.current.srcObject = stream;
// Wait for video to actually start playing
await new Promise<void>((resolve, reject) => {
const video = videoRef.current!;
const timeout = setTimeout(() => reject(new Error('timeout')), 8000);
video.onloadedmetadata = () => {
clearTimeout(timeout);
video.play().then(resolve).catch(reject);
};
video.onerror = () => {
clearTimeout(timeout);
reject(new Error('video error'));
};
});
if (mountedRef.current) {
setLoading(false);
}
}
} catch (err) {
if (!mountedRef.current) return;

const error = err as DOMException;
if (error.name === 'NotAllowedError' || error.name === 'PermissionDeniedError') {
setError('Kamera-Zugriff wurde verweigert. Bitte erlaube den Zugriff in den Browser-Einstellungen und versuche es erneut.');
} else if (error.name === 'NotFoundError' || error.name === 'DevicesNotFoundError') {
setError('Keine Kamera gefunden. Stelle sicher, dass dein Gerät eine Kamera hat.');
} else if (error.name === 'NotReadableError' || error.name === 'TrackStartError') {
setError('Kamera wird von einer anderen App verwendet. Schliesse andere Kamera-Apps und versuche es erneut.');
} else if (error.name === 'OverconstrainedError') {
// Retry without specific facing mode
try {
const fallbackStream = await navigator.mediaDevices.getUserMedia({
video: true,
audio: false,
});
if (!mountedRef.current) {
fallbackStream.getTracks().forEach((t) => t.stop());
return;
}
streamRef.current = fallbackStream;
if (videoRef.current) {
videoRef.current.srcObject = fallbackStream;
videoRef.current.onloadedmetadata = () => {
if (mountedRef.current) setLoading(false);
};
}
return;
} catch {
setError('Kamera konnte nicht gestartet werden.');
}
} else {
setError('Kamera konnte nicht gestartet werden. Bitte versuche es erneut.');
videoRef.current.onloadedmetadata = () => setLoading(false);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Guard late getUserMedia result before storing stream

If the modal is closed while getUserMedia is still pending (for example, while the permission prompt is open), stopStream() runs before a stream exists, then this code still assigns the newly resolved stream to streamRef without checking whether the modal is still open. In that case the camera track can remain active in the background until the modal is reopened or the component unmounts, which is a privacy/battery regression introduced by removing the mounted/open guard.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants