Bandeja de stories

A fileira de anéis no topo de um feed: um por pessoa, colorido enquanto há algo novo, apagado quando o usuário já viu tudo. Tocar num anel abre os stories no primeiro ainda não visto, e a próxima visita, mesmo depois de recarregar, lembra até onde o usuário chegou.

Experimente

Todas as versões importam ./api, que faz o papel do seu backend: groups são as pessoas que o usuário segue com os stories que cada uma postou, no formato do StoriesGroup do player. Troque pelo seu próprio feed.

typescript
import { cdnUrl } from '@reelkit/example-data';

// Stands in for your backend: the people a viewer follows and the stories each
// one posted. Each entry has the shape of `StoriesGroup` from the stories
// player of your framework, so the list goes to the player as it is.

export interface Group {
  author: { id: string; name: string; avatar: string };
  stories: { id: string; mediaType: 'image'; src: string }[];
}

const kPeople = ['Alex', 'Sarah', 'Mike', 'Emma', 'Noah', 'Lena'];

// Uneven on purpose: a person with one story is watched to the end at once,
// one with three can be left part way and resumed.
const kStoryCounts = [3, 1, 2, 3, 1, 2];

const pad = (n: number) => String(n).padStart(2, '0');

const storyImage = (n: number) =>
  n <= 6
    ? cdnUrl(`samples/images/stories/story-00${n}.jpg`)
    : cdnUrl(`samples/images/image-${pad(n - 6)}.jpg`);

let nextImage = 1;

export const groups: Group[] = kPeople.map((name, i) => ({
  author: {
    id: `user-${i + 1}`,
    name,
    avatar: cdnUrl(`samples/avatars/avatar-${pad(i + 1)}.jpg`),
  },
  stories: Array.from({ length: kStoryCounts[i] }, (_, j) => ({
    id: `user-${i + 1}-story-${j + 1}`,
    mediaType: 'image' as const,
    src: storyImage(nextImage++),
  })),
}));
A mídia de exemplo só funciona em reelkit.dev

cdnUrl monta links para cdn.reelkit.dev, que só entrega seus arquivos aos sites do ReelKit. No seu app esses avatares e stories não carregam, então aponte avatar e src para os seus próprios arquivos antes de copiar este arquivo.

StoriesTray.tsx
Alex
Alex
Sarah
Sarah
Mike
Mike
Emma
Emma
Noah
Noah
Lena
Lena
StoriesTray.vue
Alex
Alex
Sarah
Sarah
Mike
Mike
Emma
Emma
Noah
Noah
Lena
Lena
stories-tray.component.ts
Alex
Alex
Sarah
Sarah
Mike
Mike
Emma
Emma
Noah
Noah
Lena
Lena

Assista alguém até o fim e feche o player: o anel dessa pessoa fica apagado, o foco vai para a última pessoa que você assistiu, e os dois sobrevivem a um recarregamento. "Forget what was seen" começa de novo.

Por que funciona

  • Um controller lembra pelos dois. createStoriesViewedStateController é criado uma vez e vai para a lista de anéis e para o player como viewed. Os anéis leem dele, o player registra nele cada story que mostra, e ele guarda isso no localStorage sob storageKey, então recarregar não muda nada. Veja como lembrar o que foi visto em React, Vue e Angular.
  • O player retoma de onde o usuário parou. Com viewed, o player abre uma pessoa no primeiro story ainda não visto, ou do começo quando tudo já foi visto. A receita só passa a pessoa, nunca um índice de story; quem responde é o resumeStoryIndex do controller, veja a referência dele.
  • Um anel tem dois estados. Colorido enquanto há algo para assistir, apagado quando a pessoa foi assistida até o fim. O progresso dentro de uma pessoa fica na barra de progresso do player, não no anel. Veja StoriesRing.
  • As cores do anel acompanham a página. Os dois estados são os tokens --rk-stories-ring-active-gradient e --rk-stories-ring-viewed-color, e o de visto é, por padrão, um branco discreto feito para uma página escura. Numa página clara, defina-o em .rk-stories-ring-list, como esta demo faz no tema claro, e não em :root: o carrossel de desktop do player desenha anéis com os mesmos tokens sobre o seu fundo escuro. Os tokens estão na tabela de temas.
  • Nenhuma ligação extra para o controller. O player está sempre renderizado e abre com isOpen, então ele mesmo lê o estado guardado antes de escolher o primeiro story. Se ele só for montado enquanto está aberto, a página precisa conectar o controller antes, como explica a referência do controller.
  • O foco volta para o anel certo. Ao fechar, o player devolve o foco ao anel que o abriu, como descreve a seção de acessibilidade. Isso acontece depois que o handler de fechamento rodou, então a receita espera uma tarefa, rola o anel da última pessoa assistida até ficar visível e coloca o foco nele.
  • Onde mais dá para guardar. storage recebe o seu próprio adapter, um servidor por exemplo, para o que foi visto acompanhar o usuário entre dispositivos. ttlMs faz a entrada de uma pessoa expirar, e maxTracks limita quantas pessoas são guardadas. Estão na configuração do controller.

Próximos passos