Przejdź do głównej zawartości

Flutter SDK

Pakiet przymierzto daje szklany przycisk w stylu iOS 26 do położenia na zdjęciu produktu. Dotknięcie otwiera jeden arkusz, który przechodzi przez kolejne kroki:

  • zgody (raz);
  • zdjęcie sylwetki (raz);
  • czekanie;
  • wynik ze znaczkiem AI;
  • ocenę kciukiem;
  • galerię wcześniejszych przymiarek.

Po zamknięciu arkusza przymiarka trwa dalej, a przycisk pokazuje postęp.

dependencies:
przymierzto: ^0.4.0

Wymagania: Flutter 3.41+ i iOS 15+.

iOS: dodaj do Info.plist opisy NSCameraUsageDescription, NSPhotoLibraryUsageDescription i NSPhotoLibraryAddUsageDescription (zapis wyniku w Zdjęciach, patrz Zapis i udostępnianie).

PrzymierzTo.init(
apiBase: 'https://api.przymierzto.example',
// Twój backend woła POST /v1/session-tokens dla zalogowanej klientki.
tokenProvider: () async {
final r = await myBackend.post('/przymierzto-token');
return SessionToken(r['token'], DateTime.parse(r['expires_at']));
},
theme: const PrzymierzToTheme(primary: Color(0xFF1F1B2E)),
locale: 'pl', // albo 'en'
);

Nie musisz zmieniać main() ani owijać aplikacji w nic więcej.

Stack(
children: [
Image.network(product.imageUrl, fit: BoxFit.cover),
Positioned(
right: 14,
bottom: 14,
child: PrzymierzToButton(
productId: product.id, // external_product_id
onResult: (tryOn) => analytics.track('tryon', tryOn.id),
onFeedback: (tryOn, rating) => analytics.track('tryon_rated', rating.name),
onSaved: (tryOn) => analytics.track('tryon_saved', tryOn.id),
onShared: (tryOn) => analytics.track('tryon_shared', tryOn.id),
onError: (code) => debugPrint(code),
),
),
],
)

Wariant przycisku:

  • PrzymierzToButtonStyle.compact (domyślny): szklane kółko. Napis rozwija się na start, przy czekaniu i przy gotowym wyniku, a potem zwija.
  • PrzymierzToButtonStyle.full: stała kapsuła z napisem.

Wariant ustawiasz w motywie (PrzymierzToTheme(buttonStyle: …)) albo dla jednego przycisku (style:).

Przycisku do koszyka w SDK nie ma. O zakupie decyduje Twoja aplikacja.

Produkty bez wcześniejszej synchronizacji. Jeśli nie przekazujesz katalogu przez PUT /v1/garments, podaj dane produktu przy przycisku. Pierwsza przymiarka założy produkt sama, kolejne użyją gotowej karty:

PrzymierzToButton(
productId: product.id,
product: ProductInfo(name: product.name, imageUrls: product.gallery), // najwyżej 8 zdjęć
)

Pierwsza przymiarka nowego produktu trwa wtedy dłużej o pobranie zdjęć i przygotowanie karty.

Pod wynikiem jest szklana kapsuła Zapisz | Udostępnij, a na pełnym ekranie te same dwie ikony. Obraz ma mały znaczek „Obraz AI · nazwa butiku” i oznaczenie AI w metadanych (szczegóły).

  • Zapisz kładzie obraz prosto w Zdjęciach. Przy pierwszym razie iOS pyta klientkę o dostęp (tylko dodawanie zdjęć). „Zapisano w Zdjęciach” pojawia się dopiero po udanym zapisie. Po odmowie klientka widzi prośbę o włączenie dostępu i przycisk do Ustawień.
  • Udostępnij otwiera systemowy arkusz (WhatsApp, Instagram, Wiadomości i inne).

onSaved przychodzi po udanym zapisie, onShared po wyborze celu w arkuszu. Zamknięcie arkusza bez wyboru niczego nie wysyła.

iOS: wymagany wpis w Info.plist. Bez niego SDK ukrywa przycisk „Zapisz” (zapis bez tego klucza zamknąłby aplikację) i wypisuje ostrzeżenie w logu:

<key>NSPhotoLibraryAddUsageDescription</key>
<string>Zapisujemy wynik przymiarki w Zdjęciach.</string>
<key>CFBundleAllowMixedLocalizations</key>
<true/>

Drugi klucz sprawia, że arkusz udostępniania jest po polsku także w aplikacji bez polskiej lokalizacji. Android nie potrzebuje uprawnień.

Ustaw priority: TryOnPriority.live i podmieniaj productId na aktualnie pokazywany produkt:

PrzymierzToButton(productId: live.currentProductId, priority: TryOnPriority.live)

Po zmianie produktu:

  • przycisk przełącza się na nowy produkt i rozwija napis;
  • jeśli klientka ma już wynik dla tego produktu (np. z zapowiedzi live’a), od razu pokazuje „Gotowe” z miniaturą wyniku;
  • przymiarka poprzedniego produktu kończy się w tle i trafia do galerii.

Nakładka mówi w 20 językach: polski, angielski, ukraiński, niemiecki, czeski, słowacki, litewski, łotewski, estoński, węgierski, rumuński, bułgarski, chorwacki, słoweński, francuski, hiszpański, włoski, portugalski, niderlandzki, szwedzki. Domyślnie bierze język telefonu. Klientka zmienia go w menu „···” → „Zmień język”, a wybór zostaje zapamiętany w aplikacji.

PrzymierzTo.init(
apiBase: 'https://api.przymierzto.example',
tokenProvider: ...,
locale: 'auto', // domyślnie; 'pl', jeśli chcesz zawsze zaczynać od polskiego
locales: ['pl', 'en', 'uk'], // opcjonalnie: tylko te języki
allowLocaleChange: true, // false chowa wiersz „Zmień język”
privacyUrl: 'https://sklep.pl/polityka-prywatnosci',
onOpenUrl: (uri) => launchUrl(uri), // bez tego adres pokazujemy do skopiowania
onLocaleChanged: (code) => analytics.track('tryon_locale', code),
);

Zmiana względem 0.3: init bez locale bierze język telefonu (wcześniej zawsze polski). Jeśli chcesz zachować polski, podaj locale: 'pl'.

iOS: ustawienie języka dla jednej aplikacji (Ustawienia → aplikacja → Język) działa tylko dla języków zadeklarowanych w Twojej aplikacji w Xcode.

Informacja o AI jest zawsze widoczna: zdanie pod wynikiem, zdanie pod zgodami i ekran „O przymiarce AI” w menu. Zasady dla klientek: Zasady przymiarki.

PrzymierzToTheme(glass: …):

  • GlassMode.auto (domyślnie): szkło, gdy urządzenie i ustawienia na to pozwalają.
  • GlassMode.glass: zawsze szkło.
  • GlassMode.solid: zawsze jednolita powierzchnia.

Zachowanie przy auto:

  • przy ustawieniach iOS Ogranicz przezroczystość i Zwiększ kontrast SDK rysuje jednolitą powierzchnię zamiast szkła;
  • przy Ogranicz ruch wyłącza animacje;
  • na urządzeniach bez obsługi shaderów (np. starsze Androidy) rysuje uproszczone szkło.

Potrzebujesz własnego interfejsu? Użyj PrzymierzTo.client (PrzymierzToClient):

  • profile()
  • uploadProfile()
  • createTryOn()
  • waitFor()
  • listTryOns(product:, status:, limit:, before:)
  • rate(id, rating, reasons:)
  • deleteData()

Klient sam odnawia wygasły token.

  • Usunięte: onBuy i TryOnSheet. Nowe: onFeedback.
  • Wygląd: przycisk jest szklany i ma leżeć na zdjęciu produktu (Stack + Positioned).