mirror of
https://github.com/block/buzz.git
synced 2026-11-07 09:52:03 +00:00
Replace the mobile Agents sheet with a full-page directory of verified owned agents. Add dedicated creation and avatar pages with catalog-backed model selection, reuse the profile emoji/photo/camera controls, and expose Builderbot model settings while labeling desktop agents “Manage on desktop.” Share one account-scoped model catalog across editable cards and retries. Choose Bestie from the agent profile using the shared encrypted main-agent record (text-only action, filled star once selected), and move confirmed deletion to a top-left trash control with native iOS glass. Include uploaded avatars in owner registrations so desktop can display them. Validation: mobile analysis and all 3,958 hosted-enabled app tests passed; default-build tests run by the push hook. Earlier iPhone build installed and iterated with the user; the current iOS build succeeds, but final changes still need a device pass. Independent review found no new blockers. Actual camera capture and live Bestie sync remain unconfirmed; the existing shared `main-agent` wire format and Bestie terminology are retained. ### Snapshots Widget-harness captures with test data (not native iOS chrome). | Agents directory | Image avatar editor | | --- | --- | |  |  | --------- Signed-off-by: kenny lopez <klopez4212@gmail.com> Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz>
72 lines
2.1 KiB
Dart
72 lines
2.1 KiB
Dart
import 'dart:async';
|
|
|
|
/// Serializes camera teardown so replacement sessions never overlap.
|
|
///
|
|
/// A native disposal failure is intentionally contained: callers can proceed
|
|
/// with the next camera session after the failed release has settled.
|
|
class CameraDisposalBarrier {
|
|
Future<void> _pending = Future<void>.value();
|
|
|
|
/// Reserves camera ownership while a controller is initializing.
|
|
CameraDisposalReservation reserve() {
|
|
final reservation = CameraDisposalReservation._(_pending);
|
|
_pending = reservation._settled;
|
|
return reservation;
|
|
}
|
|
|
|
/// Completes after earlier and [dispose] callbacks have settled.
|
|
///
|
|
/// Exceptions from [dispose] are handled so they cannot prevent a later
|
|
/// replacement session from acquiring the camera.
|
|
Future<void> release(Future<void> Function() dispose) {
|
|
final previous = _pending;
|
|
final release = () async {
|
|
await previous;
|
|
try {
|
|
await dispose();
|
|
} catch (_) {
|
|
// A failed native release must not permanently block camera recovery.
|
|
}
|
|
}();
|
|
_pending = release;
|
|
return release;
|
|
}
|
|
|
|
/// Completes once all scheduled teardown work has settled.
|
|
Future<void> get settled => _pending;
|
|
}
|
|
|
|
/// Owns one in-flight camera initialization in a [CameraDisposalBarrier].
|
|
class CameraDisposalReservation {
|
|
CameraDisposalReservation._(this._previous) {
|
|
_settled = () async {
|
|
await _previous;
|
|
await _completion.future;
|
|
}();
|
|
}
|
|
|
|
final Future<void> _previous;
|
|
final _completion = Completer<void>();
|
|
late final Future<void> _settled;
|
|
|
|
/// Waits for older camera teardown before this candidate initializes.
|
|
Future<void> get ready => _previous;
|
|
|
|
/// Releases this reservation after a successful initialization.
|
|
void complete() {
|
|
if (!_completion.isCompleted) _completion.complete();
|
|
}
|
|
|
|
/// Disposes a failed or cancelled candidate before allowing replacement.
|
|
Future<void> dispose(Future<void> Function() release) async {
|
|
await _previous;
|
|
try {
|
|
await release();
|
|
} catch (_) {
|
|
// A failed native release must not permanently block camera recovery.
|
|
} finally {
|
|
complete();
|
|
}
|
|
}
|
|
}
|