Tags

Tags give the ability to mark specific points in history as being important
  • v2.5.0

    protected
    v2.5.0
    
    Post templates move from the browser to the account, and the dialog they are
    edited from is usable on a phone (MR !181). Requires nexus-go v2.2.0 or later,
    which is deployed on both nodes.
    
    - Templates lived in localStorage under blurtPostTemplates-<user>, so they were
      per-browser and per-device, lost with site data, and absent from a private
      window. They are now rows in nexus-go, reached through five signed RPCs.
      Every operation is signed on its own and deliberately does not use the draft
      session grant: that grant is a bearer credential meant to spare a signature
      on each draft autosave, and template operations are rare enough to pay for
      themselves.
    
    - Writes fan out to every node and reads merge what every node returns, with
      last-write-wins and tombstones for deletes, exactly as drafts do. A list from
      zero reachable nodes is UNKNOWN rather than "you have none", so an outage
      never looks like data loss.
    
    - A modal asks once, before the editor stops reading the browser's copy, and
      clears that copy only after every template is confirmed stored. It was the
      only copy.
    
    - A /templates page, sibling of /drafts and beside it in the account menu,
      lists what the account holds, opens one into the editor, and deletes with a
      confirmation that says the delete cannot be undone -- because it cannot.
      Deleting used to sit in Advanced Settings as a second button identical to the
      one next to it and one click from Load.
    
    - The beneficiary row is no longer a twelve-column grid on a phone. Splitting
      those columns between a three-character percentage and an account name never
      worked at any share: the percentage clipped or the name was cramped. The
      percentage now takes exactly the width three digits need and the name takes
      the rest. Everything in the row centres against it, the @ box is transparent
      rather than Foundation's near-white, and Advanced Settings has a Cancel
      button at all -- its only way out was the corner X.
    
    - Adding a beneficiary over an unfinished row used to produce a second blank
      row and a duplicate-beneficiary error, because two blank rows cannot be told
      apart. Add is hidden while any row lacks a name or a percentage.
    
    - The template picker and the community role picker no longer hand the choice
      to the operating system's own picker, which cannot be styled and covers a
      dialog with a sheet that looks nothing like the site.
    
    - Below 640px a site-wide rule gives every table display:block so it can
      scroll, and a block box shrinks to its content -- so a narrow table stopped
      filling its card and read as one that had failed to load. The templates list
      and the community roles table use a wrapper that keeps the table a table.
    
    - Two i18n sections, post_template_selector_jsx and beneficiary_selector_jsx,
      existed only in English and rendered that way whatever the reader's language.
      Both are translated into the other eight locales. Add account and Remove now
      say Add beneficiary and Remove beneficiary; Sign in and Sign up, a letter
      apart and neither saying what it does, say Login and Register.
    
    Also in this release, with no effect on what users see: the repository gained a
    jest configuration and a green suite where twelve of its suites had been
    failing, a CI job that runs it on every merge request with the results and
    coverage shown there, and an npm install that survives a socket timeout instead
    of failing the pipeline before anything is tested (MRs !177, !178, !179, !180).
  • v2.4.1

    protected
    v2.4.1
    
    The editor's beneficiary shares, built and announced from one place (MR !176).
    
    - The editor announced beneficiary shares with arithmetic that disagreed with
      what it went on to broadcast: the dialog counted the form rows while the
      operation was assembled separately, so the two could drift. Across the
      configurations the validator accepts, the announced total was wrong in about
      one in five, and some announcements added up to more than 100%, which the
      chain cannot represent. The summary and the operation now come from a single
      buildBeneficiaries(), so what the author is shown is the list that is sent.
    
    - Automatic shares stay fixed. The community's and the referrer's 3% are never
      reduced, trimmed, or edited away. What the author adds is added on top, and
      when the total will not fit it is the author's own shares that yield,
      largest first. An account earning several shares becomes one entry with
      their sum, which is what the chain requires: it rejects a beneficiary listed
      twice. The convention is client-side and so unenforceable in the browser;
      the editor at least no longer offers the reduction itself.
    
    - The summary names each share's origin -- community, referrer, or set by the
      author -- on its own line, in place of the aggregate counter. The count
      corrected by !169 can no longer go wrong because nothing is counted any
      more: every share is listed with the amount it actually contributes.
    
    - validateBeneficiaries() now measures the author's shares against what is
      left, taking both the automatic percentages and the slots they occupy out of
      the budget, so validation and construction agree rather than each guessing.
      It also tolerates lists that reached it without passing through the form,
      which a hand-edited page can produce.
    
    - Applying a loaded template writes to the editor's store, not only to the
      dialog, so a template's beneficiaries survive being loaded.
  • v2.4.0

    protected
    v2.4.0
    
    Security and availability fixes for the AI proxy and server-side rendering,
    plus the beneficiary lines in the editor (MRs !168, !170, !171, !172, !173,
    !174, !175).
    
    - Security: the AI proxy took the upstream endpoint from the request body and
      passed it to fetch unchecked, so anything the server could reach a caller
      could reach through it, with the response returned verbatim. Endpoints now go
      through a guard that allows https only, refuses addresses that are not
      publicly routable, and rejects redirects, checking the address inside the
      connection's DNS lookup so it covers the one actually connected to. The
      routes also require the same CSRF token the rest of the API does, which stops
      the proxy being usable as an open relay towards any public host. node-fetch
      becomes a direct dependency at 2.7.0: it was present only transitively at
      1.7.3, which leaks the Authorization header on a cross-host redirect.
    - The AI proxy had never worked in a container. fetch was used but never
      imported, and the image runs Node 16, which has no global fetch, so every
      call answered 500. Fixing that alone would have armed the hole above, so both
      land together.
    - Rate limiting: rateLimitReq ignored its own limit argument, keyed on a header
      the client writes, and never expired its entries. It now takes a per-minute
      budget counted per route over a sliding window, identifies the visitor by
      CF-Connecting-IP where the deployment declares it is behind Cloudflare, and
      evicts the oldest entries at its ceiling rather than turning new callers away.
    - Availability: a failing remote document no longer kills a worker. The pinned
      posts, dapps and nsfw lists are fetched from raw URLs, and a redirect, an
      HTML error page or a rate-limited RPC each produced an uncaught exception or
      a promise that never settled. Fetching is now one helper that always settles,
      entries that cannot be read are skipped rather than failing the batch, each
      loader keeps its last good value, and an unhandled rejection is logged
      instead of ending the worker.
    - The AI model picker asks the provider which models the key may use instead of
      offering a list compiled into the client, which had gone stale to the point
      where every option failed. The model can always be typed. Upstream failures
      answer 400 with the provider's message rather than a status a CDN replaces
      with its own error page.
    - The AI chat now streams: the event stream was being gzipped, which held the
      answer back until it was complete. Reasoning models no longer print their
      chain of thought as the answer, the settings screen and the chat share one
      configuration store, and code spans are legible in the dark theme.
    - Logging out clears the assistant. Its conversation and the provider API key
      live in the browser, so both survived a logout and the next person at that
      machine could read the chat and spend the key. Expanding the chat window no
      longer hides its own toolbar behind the site header.
    - Editor: the beneficiary lines print a total when more than one automatic
      share applies and name the origin of each, instead of showing two identical
      lines that contradicted the counter. Translated into the remaining locales.
  • v2.3.4

    protected
    v2.3.4
    
    Two vote-reliability fixes (MRs !165, !166).
    
    - Vote: a broadcast error no longer erases the user's own vote unless the node
      contradicts it. blurtjs retries the same signed transaction, so a vote that
      was already applied comes back as "identical to this vote", and a timeout or
      a 5xx reply gives no verdict at all; both used to clear the optimistic vote,
      emptying the heart for a vote that was on chain and carrying that stale copy
      between views. The rollback now asks the node who voted before reverting, and
      never reverts when the node cannot answer.
    - RPC: failover now fires when a node is unreachable. transport.send() reported
      its failures only through its own callback, so error_count never reached
      failover_threshold and the client stayed pinned to a dead node. The retry
      budget is bounded too (it was the library default of 10, backing off to about
      17 minutes), so the threshold is reached in seconds.
  • v2.3.3

    protected
    v2.3.3
    
    Two fixes to the reply flow.
    
    - A reply posted from a list card appeared above the post it answered. The list
      layout orders the card's children explicitly and the panel had no order of
      its own, so it sorted ahead of everything; it now sits past the footer at
      every breakpoint.
    - Opening a post that was not in the store yet showed the not-found page until
      the data arrived, most visibly through "view the full context", where the
      parent is never in the store. The page waits while the request is in flight
      and reports the post missing only once it has finished without producing it.
  • v2.3.2

    protected
    v2.3.2
    
    ESLint cleanup and the genuine errors it surfaced (MR !161).
    
    - Config: demote airbnb style rules to warnings (14,895 -> 0 errors); ignore
      vendored assets; declare jest/browser globals. CI-only, no runtime effect.
    - Fixes: latent bugs the linter had buried (undefined refs in FetchDataSaga,
      ChangePassword, Header, tape, SteemMarket, App, ...), all behavior-preserving.
  • v2.3.1

    protected
    v2.3.1
    
    Show the post-footer voters arrow whenever a post has votes.
    
    - The vote-count + voters arrow was gated on active_votes being pre-loaded in
      that copy of the post, so it appeared for some accounts/posts and not others.
      Gate it on total_votes instead; the modal already fetches the real voters on
      demand when opened (with reference-node fallbacks).
  • v2.3.0

    protected
    v2.3.0
    
    Friendly, localized error handling; mobile and deploy improvements.
    
    - In-app error toasts now show calm, human, localized messages instead of raw
      chain assertions, mapping the common Blurt transaction errors (with a generic
      fallback) across all nine locales.
    - Fix long error messages overflowing the viewport on mobile.
    - Remove the obsolete out-of-bandwidth / Resource Credits modal, which does not
      apply to Blurt (transactions are gated by fees, not a resource-credit allowance).
    - Version the per-environment deploy config in the repo so the deploy jobs ship it.
    
    Classification: MINOR — user-facing features and fixes, no breaking changes.
  • v2.1.0

    protected
    v2.1.0
    
    - Server-side post drafts
    - Accept .mov / HEVC video uploads (by extension; no client-side rejection)
    - Drop the obsolete HEVC upload guidance
    - Logged-out navigation: keep Sign in / Sign up in the side menu, open login as an in-app modal, retire /login.html
    - Show the header Sign in / Sign up CTA only from 1200px (fix the iPad-landscape overlap with the primary nav)
    - Hide the Follow button for logged-out visitors
    - Correct the sign_in mistranslation (es, fr)
    - Centre the video play badge on iOS in the expanded list view
  • v2.0.0

    protected
    v2.0.0
    
    First tagged release. Introduces tag-driven releases: production is deployed from version tags, and /__version.json reports the tag.