implemented a 1-minute in-memory cache for the EmergencyNoticeClient to prevent redundant network requests on app resume
This commit is contained in:
@@ -1,21 +1,10 @@
|
||||
/// A backend-independent emergency notice, loaded from a foreign server URL.
|
||||
///
|
||||
/// Deliberately decoupled from MarianumConnect: if that backend is unreachable
|
||||
/// (the disaster case this exists for), a plain text file on any other host can
|
||||
/// still surface a message. The file is a small YAML-ish frontmatter followed
|
||||
/// by a free Markdown body, so it stays hand-writable in an emergency — no JSON
|
||||
/// escaping of the (multi-line) content.
|
||||
///
|
||||
/// See [parse] for the exact format.
|
||||
/// A backend-independent emergency notice loaded from a foreign server URL —
|
||||
/// frontmatter (control fields) plus a free Markdown body, so it stays
|
||||
/// hand-writable in an outage. See [parse] for the format.
|
||||
class EmergencyNotice {
|
||||
/// Whether the notice can be dismissed. `false` renders it full-screen and
|
||||
/// blocks back/barrier taps.
|
||||
/// `false` renders full-screen and blocks back/barrier taps.
|
||||
final bool dismissible;
|
||||
|
||||
/// Optional heading shown above the body.
|
||||
final String? title;
|
||||
|
||||
/// Markdown body (the message itself).
|
||||
final String body;
|
||||
|
||||
const EmergencyNotice({
|
||||
@@ -24,38 +13,24 @@ class EmergencyNotice {
|
||||
required this.body,
|
||||
});
|
||||
|
||||
/// Parses the raw file into a displayable notice, or returns `null` when
|
||||
/// there is nothing to show. Never throws — any malformed input yields `null`
|
||||
/// so a broken file can never break the app.
|
||||
/// Parses the raw file, or returns `null` when there is nothing to show.
|
||||
/// Never throws — malformed input yields `null` so a broken file can't break
|
||||
/// the app.
|
||||
///
|
||||
/// Format:
|
||||
/// ```
|
||||
/// ---
|
||||
/// active: true
|
||||
/// # dismissible: false <- comment lines (# ...) are ignored
|
||||
/// dismissible: true
|
||||
/// title: Störung
|
||||
/// active: true # required truthy, else null; # lines are comments
|
||||
/// dismissible: true # default true
|
||||
/// title: Störung # optional
|
||||
/// ---
|
||||
/// # Markdown heading
|
||||
/// Free **markdown** body.
|
||||
/// Free **markdown** body (everything after the closing ---).
|
||||
/// ```
|
||||
///
|
||||
/// Rules:
|
||||
/// - The frontmatter is everything between the first `---` line and the next
|
||||
/// `---` line. Both delimiters are required.
|
||||
/// - Frontmatter entries are `key: value`; a line whose trimmed form starts
|
||||
/// with `#` is a comment. Unknown keys are ignored.
|
||||
/// - `active` (default `false`) must be explicitly true, else `null`.
|
||||
/// - `dismissible` defaults to `true`.
|
||||
/// - `title` is optional. The rest after the closing `---` is the Markdown
|
||||
/// body; an empty body yields `null`.
|
||||
static EmergencyNotice? parse(String raw) {
|
||||
final lines = raw
|
||||
.replaceAll('\r\n', '\n')
|
||||
.replaceAll('\r', '\n')
|
||||
.split('\n');
|
||||
|
||||
// Locate the opening `---` (skipping any leading blank lines).
|
||||
var i = 0;
|
||||
while (i < lines.length && lines[i].trim().isEmpty) {
|
||||
i++;
|
||||
@@ -63,7 +38,6 @@ class EmergencyNotice {
|
||||
if (i >= lines.length || lines[i].trim() != '---') return null;
|
||||
final openIndex = i;
|
||||
|
||||
// Locate the closing `---`.
|
||||
var closeIndex = -1;
|
||||
for (var j = openIndex + 1; j < lines.length; j++) {
|
||||
if (lines[j].trim() == '---') {
|
||||
|
||||
Reference in New Issue
Block a user