Modale anteprima argomento

Installa questo componente di tema

Topic Preview Modal – apri e interagisci con gli argomenti senza lasciare l’elenco degli argomenti

Ho creato un nuovo componente di tema per Discourse chiamato Topic Preview Modal.

L’idea è piuttosto semplice:

Apri un argomento direttamente dall’elenco degli argomenti in una modale nativa di Discourse, leggi e interagisci con l’argomento, quindi continua a sfogliare l’elenco senza navigare altrove.

È nato da Facebook-style Topic Modal - Is it better? , ma alla fine ha richiesto un’integrazione piuttosto ampia con i sistemi di Discourse per argomenti, flusso di post, compositore, modali, segnalibri, routing, presenza, tracciamento della lettura e pre-fetching.


Perché?

Il flusso normale di Discourse è:

  1. Stai sfogliando un elenco di argomenti.
  2. Fai clic su un argomento.
  3. Discourse naviga a /t/....
  4. Leggi/rispondi/interagisci con l’argomento.
  5. Torni all’elenco degli argomenti.

Per molti flussi di lavoro, questo va benissimo.

Tuttavia, quando si sfoglia un elenco di argomenti molto attivo, a volte si vuole solo ispezionare rapidamente un argomento, leggere alcuni post, controllare le ultime risposte, reagire a qualcosa o rispondere a una domanda veloce.

Per quel caso d’uso, lasciare l’elenco degli argomenti sembra un costo ingiustificato.

L’obiettivo di questo componente era quindi far sì che l’elenco degli argomenti si comportasse più come una casella di posta:

elenco argomenti → anteprima → interazione → chiusura → continua esattamente da dove eri.


Cosa fa

L’anteprima non è solo un estratto statico.

Rende i componenti post reali di Discourse all’interno di una DModal nativa.

Ciò significa che gli utenti possono:

  • leggere i post
  • scorrere l’argomento
  • caricare post precedenti
  • caricare altri post sotto
  • reagire ai post
  • mettere in segnalibro i post
  • citare il testo
  • rispondere all’argomento
  • rispondere a singoli post
  • modificare i post se consentito
  • eliminare/recuperare i post se consentito
  • segnalare i post
  • visualizzare la cronologia dei post
  • eseguire varie normali azioni sui post
  • vedere la presenza dell’argomento
  • seguire i link ad altri post all’interno dello stesso argomento
  • saltare direttamente al post rilevante
  • aprire l’argomento completo se necessario

L’intenzione è che l’anteprima dovrebbe sentirsi il più possibile come l’apertura effettiva dell’argomento.


Due modalità di attivazione

Ci sono due modi per aprire l’anteprima.

1. Riga dell’elenco argomenti intera

Questo è il comportamento predefinito.

L’intera riga dell’elenco argomenti diventa cliccabile, mentre gli elementi interattivi comuni come:

  • schede utente
  • partecipanti
  • link alle categorie
  • tag
  • link di stato dell’argomento
  • selezione multipla

sono esclusi dal trigger della modale.

Questo rende l’esperienza molto veloce quando si sfoglia un elenco di argomenti.

2. Pulsante di espansione esplicito

In alternativa, il componente può rendere un’icona di espansione piccola tramite un plugin outlet di Discourse. I temi personalizzati possono semplicemente creare un nuovo <PluginOutlet /> per mostrare il trigger.

In questa modalità, il comportamento normale dell’elenco argomenti rimane completamente intatto.

L’utente fa clic sull’icona di espansione per aprire l’anteprima, mentre fare clic sul titolo dell’argomento esegue ancora la normale navigazione di Discourse.

Questo è utile se un sito vuole preservare il modello di interazione standard dell’elenco argomenti.

L’impostazione è:

trigger_style:
  row

o:

trigger_style:
  button

Quando si usa la modalità pulsante, anche l’outlet è configurabile.


L’anteprima inizia dalla posizione non letta dell’utente

Uno dei dettagli importanti è che la modale non carica semplicemente il primo post.

Quando un argomento è stato già letto parzialmente, l’anteprima calcola:

last_read_post_number + 1

e si apre intorno a quel post.

Quindi, se un argomento ha 200 post e l’utente ha letto fino al post #165, l’apertura dell’anteprima inizia intorno al #166.

Questo rende l’anteprima molto più utile per la navigazione reale.

Significa anche che il componente deve gestire entrambi i lati del flusso di post:

  • caricare i post precedenti quando necessario
  • caricare post più recenti sotto

Il pulsante Post precedenti viene visualizzato quando ci sono post sopra l’intervallo attualmente caricato, mentre un sentinella IntersectionObserver carica automaticamente altri post quando l’utente raggiunge il fondo.


Pre-fetching

Una delle parti più grandi del componente è il suo sistema di pre-fetching.

Il problema con una modale come questa è che l’utente si aspetta che si senta istantanea.

Se iniziamo a caricare l’argomento solo dopo che l’utente fa clic, la modale può ancora impiegare un tempo notevole ad attendere la rete.

Invece, il componente può pre-fetchare proattivamente gli argomenti mentre l’utente sfoglia l’elenco.

Quando una riga di argomento si avvicina al viewport, un IntersectionObserver può programmare un pre-fetch.

Ci sono diversi meccanismi di sicurezza per impedire che questo si trasformi in traffico di sfondo incontrollato.

Debouncing

Un argomento non innesca immediatamente una richiesta solo perché è apparso brevemente nel viewport.

Il componente attende per il periodo di debouncing configurato.

Predefinito:

400 ms

Questo è particolarmente utile quando si scorre rapidamente attraverso un lungo elenco di argomenti.

Margine radice

Il pre-fetching può iniziare leggermente prima che l’argomento entri effettivamente nel viewport.

Predefinito:

50 px

Questo dà alla richiesta un piccolo vantaggio.

Limite di richieste simultanee

Il numero di pre-fetch simultanei è limitato.

Predefinito:

2

L’impostazione consente da 1 a 6 pre-fetch simultanei.

Budget per minuto

C’è anche un secondo meccanismo di protezione:

max_prefetches_per_minute

Il predefinito è:

15

Quindi, anche se l’utente continua a scorrere centinaia di argomenti, il componente non genererà continuamente richieste speculative.

0 disabilita il limite.

Il pre-fetching può essere disabilitato completamente

Se un sito non vuole traffico di rete speculativo:

enable_prefetch = false

Il componente continua a funzionare normalmente. Gli argomenti vengono semplicemente caricati quando l’anteprima viene aperta.


I dati pre-fetch sono mantenuti separati dalla normale navigazione degli argomenti

C’è un importante dettaglio di implementazione qui.

La risposta pre-fetchata non viene immediatamente scritta nella chiave di preload normale topic_<id> di Discourse.

Invece, il componente usa il proprio namespace:

topic-preview-modal:prefetch:<topicId>

Solo quando l’utente apre effettivamente l’anteprima, la promessa pre-fetchata viene promossa alla chiave di preload dell’argomento principale.

Questo è intenzionale.

L’anteprima potrebbe stare caricando un argomento a partire da last_read_post_number + 1, e non voglio che quella risposta specifica dell’anteprima finisca in una normale navigazione della rotta dell’argomento.

Quindi il ciclo di vita è essenzialmente:

c'è un argomento nel viewport
        ↓
pre-fetch
        ↓
archiviazione di preload privata
        ↓
l'utente apre l'anteprima
        ↓
promozione del preload
        ↓
Topic.find()/PostStream usa la stessa promessa

Questo significa anche che la modale non deve aspettare che la richiesta di pre-fetch finisca prima di aprirsi.

La modale può aprirsi immediatamente con il suo scheletro mentre la stessa promessa continua a risolvere.


Supporto mobile

Questo è in realtà stato uno dei motivi per cui ho speso considerevolmente più tempo sull’implementazione.

L’idea iniziale funzionava ragionevolmente bene su desktop, ma il mobile ha evidenziato diversi problemi riguardanti:

  • interazione touch
  • scorrimento della modale
  • focus
  • menu annidati
  • il compositore
  • visibilità dei post
  • caricamento delle immagini
  • prestazioni

L’implementazione finale evita quindi di trattare la modale come un mini forum completamente separato.

Invece, riutilizza la maggior parte possibile dell’infrastruttura esistente di Discourse.


Componenti post reali di Discourse

La modale non ricrea i post usando un template personalizzato semplificato.

Rende i componenti reali di Discourse:

Post
PostSmallAction

Questo è importante perché altrimenti l’anteprima diventerebbe rapidamente una seconda implementazione dell’interfaccia dei post.

Il componente passa le azioni rilevanti ai normali componenti post, inclusi elementi come:

  • risposta
  • modifica
  • eliminazione
  • recupero
  • segnalazione
  • cronologia
  • segnalibro
  • wiki
  • blocco/sblocco
  • tipo di post
  • cambi di proprietà
  • badge
  • post nascosti
  • citazione
  • ecc.

Il risultato è che l’anteprima può comportarsi molto più come un argomento normale che come un tradizionale componente di “anteprima”.


Risposte e compositore

Il compositore è una delle parti più complicate.

L’anteprima può aprire il normale compositore di Discourse per:

Rispondere all’argomento

Il compositore dell’argomento viene aperto con il modello dell’argomento e le informazioni corrette sulla bozza.

Rispondere a un post specifico

Il post viene passato al compositore in modo che la risposta si comporti come una normale risposta a un post.

Citare il testo selezionato

Il componente si integra anche con PostTextSelection.

Ciò significa che gli utenti possono selezionare il testo all’interno dell’anteprima e usare il normale flusso di citazione/risposta di Discourse.


Modali annidate

Un’altra parte difficile è stato il sistema di modali di Discourse.

I post possono aprire altre modali e dialoghi:

  • segnalazione
  • cronologia
  • dialoghi relativi ai badge
  • cambi di proprietà
  • conferme di eliminazione
  • ecc.

Se questi fossero permessi di interagire normalmente con il servizio di modale globale, l’apertura di uno di essi potrebbe chiudere l’intera anteprima dell’argomento.

Per evitare ciò, il componente crea un meccanismo di sotto-modale locale.

Concettualmente:

Modale Anteprima Argomento
        │
        ├── Modale Segnalazione
        ├── Modale Cronologia
        ├── Conferma Eliminazione
        ├── Modale Badge
        └── altra modale relativa ai post

L’anteprima rimane montata sotto.

Il componente applica temporaneamente patch ai metodi rilevanti del servizio di modale mentre è attivo e li ripristina quando viene distrutto.


Routing all’interno della modale

Un altro dettaglio importante sono i link a post all’interno dello stesso argomento.

Ad esempio, se un post contiene un link a:

/t/my-topic/123

l’anteprima non ha bisogno di chiudersi e navigare altrove.

Invece, il componente intercetta la navigazione all’interno dello stesso argomento e salta al post richiesto all’interno della modale.

Lo stesso vale per i link che puntano all’argomento senza un numero di post specifico.

Questo mantiene l’utente all’interno dell’anteprima.

Se il link punta a un argomento genuinamente diverso, il componente prima ripristina le sue patch temporanee del servizio e si chiude prima di consentire la normale transizione di rotta di Discourse.

Quella pulizia è importante perché altrimenti le sottoscrizioni e il tracker di tempi dell’anteprima potrebbero rimanere attivi mentre la rotta dell’argomento reale viene inizializzata.


Tracciamento della lettura e tracciamento del tempo

Volevo anche che l’anteprima si comportasse correttamente dal punto di vista di Discourse.

Aprire un’anteprima non dovrebbe significare che il tracciamento della lettura viene completamente eluso.

Il componente gestisce quindi:

  • tracciamento delle visite all’argomento
  • tracciamento dei post visibili
  • tempistica dell’argomento
  • aggiornamenti dell’ultimo post letto

Il tracker di tempistica usa un IntersectionObserver per determinare quali post sono effettivamente visibili.

Ogni 5 secondi, la tempistica dei post visibili viene inviata a:

/topics/timings

Quando la modale si chiude, viene eseguito un ultimo invio in modo che gli ultimi secondi non vadano persi.

L’implementazione limita anche un singolo intervallo di tempistica a 60 secondi.


Mantenere lo stato non letto dell’elenco argomenti sincronizzato

C’era un altro problema sottile qui.

Aggiornare solo lo stato di tracciamento degli argomenti di Discourse non è sufficiente per aggiornare il badge non letto mostrato direttamente su una riga dell’elenco argomenti.

Il componente aggiorna quindi l’oggetto argomento effettivo associato alla riga dopo che le informazioni di tempistica sono state inviate.

Aggiorna valori come:

last_read_post_number
unread_posts
unread
new_posts

quando appropriato.

Questo significa che dopo aver letto un argomento all’interno della modale, l’elenco argomenti può riflettere immediatamente il nuovo stato di lettura senza richiedere un aggiornamento completo della pagina.


Visibilità dei post

L’anteprima usa un IntersectionObserver condiviso per determinare quando i singoli post diventano visibili.

C’è anche un controllo di visibilità sincrono quando l’osservatore è collegato.

Questo gestisce un caso limite in cui un post è già visibile quando viene montato, ma la prima callback asincrona di IntersectionObserver non è ancora stata eseguita.

Questo è particolarmente rilevante per argomenti molto brevi in cui l’intero argomento potrebbe già essere visibile quando la modale si apre.


Considerazioni sulle prestazioni

Un obiettivo principale era evitare di trasformare la modale in una pagina argomento miniaturizzata pesante in termini di prestazioni.

Vengono fatte alcune cose specificamente per questo.

Rendering progressivo

Il caricamento iniziale non rende immediatamente ogni post.

Il componente rende prima abbastanza post per raggiungere la posizione target.

I post rimanenti vengono quindi resi progressivamente usando:

requestIdleCallback

quando disponibile, con un fallback a setTimeout.

Questo è particolarmente utile quando si apre un argomento lungo intorno a un post in fondo al flusso.

Containment CSS

I post usano:

contain: layout;
content-visibility: auto;
contain-intrinsic-size: 1px 180px;

Questo consente al browser di evitare di eseguire lavoro di rendering non necessario per i post che non sono attualmente visibili.

Immagini lazy

Le immagini che non hanno già specificato una modalità di caricamento vengono automaticamente dotate di:

loading="lazy"
decoding="async"

Questo impedisce a un argomento lungo con molte immagini di caricare immediatamente tutto.


Stato di caricamento

La modale non mostra solo un’area bianca/vuota mentre la richiesta viene eseguita.

Ha un’interfaccia a scheletro con:

  • segnaposto per avatar
  • segnaposto per nome utente/nome
  • segnaposto per il corpo del post
  • animazione shimmer

Lo shimmer rispetta:

prefers-reduced-motion

in modo che l’animazione sia disabilitata per gli utenti che hanno richiesto la riduzione del movimento.


Mantenere la posizione di scorrimento stabile

Ci sono alcuni punti in cui il componente deve manipolare manualmente la posizione di scorrimento.

Ad esempio, quando si caricano post precedenti, il contenuto inserito aumenta l’altezza di scorrimento.

Semplicemente anteporre i post farebbe saltare la posizione attuale dell’utente.

Il componente registra quindi l’altezza di scorrimento precedente e compensa la differenza dopo che i post sono stati inseriti.

Questo mantiene il contenuto attualmente visibile approssimativamente nello stesso posto.

Lo stesso vale quando si salta a un post particolare.

Il componente esegue un passaggio di posizionamento post-rendering e verifica di nuovo la posizione nei frame successivi per tenere conto del contenuto che potrebbe ancora stabilizzarsi.


Presenza dell’argomento

Quando i dati rilevanti dell’argomento sono disponibili, l’anteprima può anche visualizzare le informazioni di presenza dell’argomento di Discourse nella parte inferiore della modale.

In questo modo gli utenti possono vedere chi altro sta attualmente visualizzando l’argomento senza dover lasciare l’anteprima.


Interazione con menu mobili e focus

Il mobile ha introdotto un’altra categoria di problemi.

Alcuni elementi dell’interfaccia di Discourse usano servizi di modale/menu condivisi, e quei servizi non sanno necessariamente che l’anteprima dell’argomento sta attualmente agendo come un contesto di navigazione annidato.

Il componente ha quindi una gestione aggiuntiva intorno a:

  • modal.close()
  • menu Float Kit
  • ripristino del focus
  • il compositore
  • controlli da tastiera del lightbox
  • blocchi di scorrimento del corpo

Ad esempio, se un menu tenta internamente di chiamare il metodo di chiusura della modale globale, ciò non dovrebbe chiudere accidentalmente l’intera anteprima dell’argomento.

Similmente, quando il compositore è aperto, il focus deve rimanere all’interno del compositore invece di essere richiamato nel contesto di focus dell’anteprima.


Configurazione

Il componente espone attualmente le seguenti impostazioni:

Impostazione Predefinito Descrizione
trigger_style row Rende l’intera riga cliccabile o usa un pulsante esplicito
plugin_outlet topic-list-after-title Outlet usato dal trigger del pulsante
enable_prefetch true Abilita/disabilita il pre-fetching di sfondo degli argomenti
max_concurrent_prefetches 2 Numero massimo di richieste di pre-fetch simultanee
prefetch_debounce_ms 400 Ritardo prima di iniziare un pre-fetch
prefetch_root_margin_px 50 Inizia il pre-fetching a questo numero di pixel prima che la riga entri nel viewport
max_prefetches_per_minute 15 Numero massimo di richieste speculative al minuto

I controlli di pre-fetching sono intenzionalmente configurabili perché comunità diverse possono avere modelli di traffico e caratteristiche di hosting/rete molto diverse.


Uno degli obiettivi di progettazione principali: non rompere il Discourse normale

Ho cercato di mantenere il componente il più vicino possibile all’architettura esistente di Discourse.

Non implementa il proprio renderer di post, il proprio compositore, il proprio modello di argomento o il proprio flusso di post completamente separato.

Invece, costruisce un contesto di navigazione temporaneo intorno ai componenti e servizi esistenti di Discourse.

Questo è anche il motivo per cui alcune parti dell’implementazione sono più complicate di quanto potrebbero apparire inizialmente.

La sfida più interessante è stata:

Un argomento può comportarsi quasi come un normale argomento Discourse mentre viene effettivamente visualizzato all’interno di un altro contesto di interfaccia utente?

Ciò ha richiesto di gestire i confini tra i servizi globali di Discourse e l’anteprima locale.

18 Mi Piace

Per tua informazione:

Ha problemi con la matematica. Tuttavia, questo potrebbe essere un altro caso limite.

1 Mi Piace

Assolutamente leggenda :slight_smile: ora devo capire come far funzionare tutto questo con la mia configurazione :slight_smile: @awesomerobot da cosa dipende il tuo tema per il click su tutta la riga?

api.renderInOutlet("topic-list-before-link", TopicListItemClick);
2 Mi Piace

Per chiunque utilizzi il tema simile a Reddit, ecco una soluzione che ho trovato funzionante.

Compatibilità con il tema simile a Reddit

Una nota per chi utilizza il tema simile a Reddit: il pulsante della finestra modale funziona, ma il trigger di riga predefinito no.

Il problema è che il tema simile a Reddit sostituisce il comportamento standard della riga dell’elenco degli argomenti e gestisce i clic sull’intera scheda dell’argomento. Di conseguenza, la gestione normale dei clic sulla riga della finestra modale non funziona come previsto.

Modificando l’impostazione della finestra modale di anteprima dell’argomento in:

Stile trigger: pulsante
Presa del plugin: topic-list-after-title

funziona correttamente, perché il tema simile a Reddit include già la presa topic-list-after-title.

Per mantenere il comportamento del clic sull’intera scheda, ho lasciato la finestra modale di anteprima dell’argomento in modalità pulsante e ho modificato l’azione openTopic() esistente del tema simile a Reddit in modo che attivi il pulsante funzionante della finestra modale.

L’azione originale del tema simile a Reddit è:

@action
openTopic(event) {
  if (
    (event.target.nodeName === "A" && !event.target.closest(".raw-link")) ||
    event.target.closest(".badge-wrapper")
  ) {
    return;
  }

  const { navigateToTopic, topic } = this.args.outletArgs;

  if (wantsNewWindow(event)) {
    window.open(topic.lastUnreadUrl, "_blank");
  } else {
    navigateToTopic(topic, topic.lastUnreadUrl);
  }
}

L’ho modificata in:

@action
openTopic(event) {
  if (
    (event.target.nodeName === "A" && !event.target.closest(".raw-link")) ||
    event.target.closest(".badge-wrapper") ||
    event.target.closest(".topic-preview-modal__trigger-wrapper")
  ) {
    return;
  }

  const { navigateToTopic, topic } = this.args.outletArgs;

  if (wantsNewWindow(event)) {
    window.open(topic.lastUnreadUrl, "_blank");
    return;
  }

  const previewButton = event.currentTarget.querySelector(
    ".topic-preview-modal__trigger-wrapper--button"
  );

  if (previewButton) {
    event.preventDefault();
    event.stopPropagation();
    previewButton.click();
    return;
  }

  navigateToTopic(topic, topic.lastUnreadUrl);
}

Il trigger del pulsante della finestra modale è reso come:

<div class="topic-preview-modal__trigger-wrapper">
  <span
    role="button"
    class="topic-preview-modal__trigger-wrapper--button"
  >

Quindi questo non ricrea alcuna logica della finestra modale. Semplicemente fa sì che il clic sulla scheda del tema simile a Reddit attivi il pulsante di anteprima esistente e funzionante.

Il risultato è:

  • Il clic sulla scheda dell’argomento apre la finestra modale di anteprima.

  • Il clic sul titolo dell’argomento apre la finestra modale di anteprima.

  • Il pulsante di anteprima continua a funzionare.

  • Il clic con Cmd/Ctrl apre ancora l’argomento normale in una nuova scheda.

  • La categoria e gli altri link normali continuano a comportarsi normalmente.

  • Se il pulsante di anteprima non è presente, il tema simile a Reddit torna alla normale navigazione degli argomenti.

Quindi la finestra modale sottostante funziona bene con il tema simile a Reddit; l’incompatibilità è specifica con il trigger di riga predefinito.

Ho anche nascosto il pulsante utilizzando

.topic-preview-modal__trigger-wrapper {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
}
3 Mi Piace

Ora provo a far funzionare le risposte annidate nella finestra modale :slight_smile:

1 Mi Piace

Tu, amico mio, sei fantastico. Questo deve essere il componente del tema più incredibile che abbia visto da un po’.

L’unica cosa che mi manca è una larghezza maggiore / configurabile; sarebbe bello poterla rendere uguale a quella dei post nella vista dell’argomento.

2 Mi Piace

Ho regolato la larghezza massima a 800px

    .d-modal {
        --modal-max-width: 600px;
        --modal-width: 30em;
        --modal-min-width: 400px;
    }
1 Mi Piace

Questo si applicherebbe a tutti i modali…
Ho fatto anche questo, per far risaltare meno l’icona

.topic-preview-modal__trigger-wrapper--button .d-icon {
    fill: #888;
}

@media (width >= 40rem) {
  .d-modal.topic-preview-modal {
      --modal-max-width: 800px;
  }
}
2 Mi Piace

@Don Sono curioso: perché non hai riutilizzato il componente <PostList> del core?

1 Mi Piace

Ciao @Jagster, grazie per la segnalazione! Ecco la correzione: FIX: Replace visibility:hidden to allow MathJax rendering · VaperinaDEV/discourse-topic-preview-modal@f9eb70f · GitHub


Grazie @RGJ, ho aggiunto un’impostazione per questo.


Questa è una buona domanda.

PostList/PostListItem è progettato per elenchi riassuntivi basati su estratti (bozze, segnalibri, feed attività), non per il rendering del flusso di post interattivo effettivo di un argomento.

Rende @post.excerpt/expandedExcerpt tramite DDecoratedHtml, più un’intestazione con avatar/titolo e un pulsante per espandere l’estratto. Non ci sono azioni di like, citazione, risposta, modifica o segnalazione: nessuna della meccanica interattiva dei post di cui la modale ha bisogno.

Anche la paginazione di PostList è unidirezionale (fetchMorePosts aggiunge solo scorrendo verso il basso), mentre la modale deve aprirsi sull’ultimo post letto e caricare sia i post precedenti che quelli successivi intorno ad esso: questo richiede il caricamento a intervalli del vero servizio postStream, non un semplice callback fetch-more.

Quindi riutilizzare PostList avrebbe significato reimplementare la maggior parte del comportamento interattivo di Post e il caricamento bidirezionale di postStream sopra un componente costruito per un lavoro diverso. Utilizzare invece il componente core Post effettivo + postStream direttamente garantisce che la modale si comporti identicamente alla pagina reale dell’argomento.

3 Mi Piace

È funzionante con le viste nidificate, necessita di ulteriori test e probabilmente di aggiungere un’opzione nell’area admin. Alcune persone hanno iniziato a usarlo, Don, e spinge gli utenti a fare più richieste e a rimanere sul sito più a lungo, poiché è così fluido e facile da scorrere, ecc. Hai fatto un lavoro incredibile con questo

4 Mi Piace

Sto testando ora! Miglioramento dell’interfaccia utente davvero impressionante

2 Mi Piace

Abbiamo disperatamente bisogno di potenziamenti qui, ma con quei tempi di risposta sono un po’ preoccupato — state ancora vivi? :laughing:

Grazie :sign_of_the_horns:

3 Mi Piace

Domanda: perché il border-top di .topic-avatar finisce per apparire come un separatore tra la parte del post precedente che rimane visibile durante lo scorrimento e l’inizio del post corrente? L’intento di questo border-top è davvero questo, o esiste qualche regola di posizionamento/overflow che causa questo comportamento?

@media (width >= 40rem) {
    .topic-avatar {
        border-top: 1px solid var(--content-border-color);
        padding-top: var(--space-4);
        width: var(--topic-avatar-width);
        float: left;
        z-index: 2;
        height: 100%;
        overflow-anchor: none;
    }
}
1 Mi Piace

Penso che questa funzione potrebbe essere molto utile per visualizzare rapidamente i post quando non si vuole aspettare il caricamento completo della pagina. Mi piacerebbe molto se ci fosse un’opzione per far sì che i clic sulle notifiche aprissero la finestra modale invece dell’elenco delle discussioni.

1 Mi Piace

Ciao @Don, dopo aver sperimentato con questo fantastico componente per 24 ore, una cosa che mi è piaciuta molto è stata la possibilità di chiudere scorrendo verso il basso, poiché ho notato che non dovevo muovere il pollice e la mano, rendendo l’uso del sito molto semplice. Tuttavia, per gli argomenti più lunghi, lo scorrimento verso l’alto non era ottimale.

Per risolvere questo problema, ho aggiunto la possibilità di chiudere scorrendo verso destra su mobile. Questo ha tutto il suo senso e, per chi desidera uno scorrimento rapido, funziona alla grande, secondo il mio parere. Cosa ne pensi?

Il link per testare è https://www.carptalk-online.co.uk/ e, ovviamente, funziona solo su mobile.

3 Mi Piace

Ho provato il tuo forum, Damian, e questa azione di scorrimento è davvero perfetta. Ottimo lavoro, come sempre!

Mi chiedo se questo componente del tema debba funzionare in Horizon. L’ho provato su due versioni e mostra un errore agli amministratori in alto. Sembra non essere compatibile?

Spero che possa funzionare; mi piace molto questa nuova prospettiva su cui lavorare.

2 Mi Piace

Che errore stai ricevendo?

2 Mi Piace

Ciao :waving_hand:

Ho aggiunto una nuova impostazione chiamata: open_all_topic_links.

Quando abilitata, QUALSIASI link che punta a un argomento in qualsiasi punto della pagina (contenuto dei post, notifiche, scheda utente, risultati di ricerca, argomenti suggeriti/correlati, barra laterale, ecc.) apre la modale di anteprima invece di navigare altrove — non solo le righe dell’elenco degli argomenti. Un link a un post specifico apre la modale scorrendo fino a quel post. I link all’interno dell’elenco degli argomenti e all’interno di una modale di anteprima già aperta mantengono il loro comportamento esistente.

5 Mi Piace

Sei la vera GOAT delle modali :slight_smile: c’è la possibilità di aggiungere la chiusura con swipe a destra su mobile nel core e di supportare le viste annidate :eyes:

2 Mi Piace