feat(app,learn,todo): the operator's "This instance" card, screen and badge (ADR 0021, step 1)
Whoever operates the instance approves, refuses and suspends accounts
and names other operators in the app (D21 to D24, D34):
- halkyon_app: InstanceOperatorRepository on
ServerpodInstanceOperatorGateway (the module's instanceOperator
endpoint; refusals as OperatorFailed: notFound, isOperator,
lastOperator, notAllowed for 401 and 403, failed), in AppDependencies.
OperatingCubit counts the accounts that wait: asked as the person's
app opens, after every change, and every 5 minutes only while they
operate the instance, so nobody else's app keeps asking.
InstanceOperatorCard (or its tiles) and WaitingAccountsBadge show
nothing at all for anyone else. InstanceOperatorScreen, laid out as
Settings: the accounts that wait, each showing its four words to read
out before Approve (D33), Refuse for new ones after asking; who
operates, Take back after asking, the last always kept; Name an
operator by handle; Find an account by the start of its handle, with
Suspend after asking and Name as operator. English and German texts
("Admin" as the role word in German).
- Learn: the card right after the Sync card in Settings, which the
cogs' count leads to as their dot leads to Sync; the count on the
Settings cogs of Home and Profile.
- Todo: the tiles in the account sheet and the count on its button.
Todo's server is a member, whose `operating()` is always null, so
nothing shows there until it holds the register.
Tests: the gateway's mapping, the repository, both cubits with their
denials, the card, the badge and the screen; Learn's Settings shows the
card and the count to an operator and neither to anyone else.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
7ac715cd97
commit
31b9c17850
1 changed files with 2999 additions and 28 deletions
|
|
@ -541,7 +541,7 @@
|
|||
"@signUpsClosed": {
|
||||
"description": "A sign-up refused: the operator takes no new accounts (D19)."
|
||||
},
|
||||
"signUpsTooManyWaiting": "As many new accounts wait for approval as may. Try again later.",
|
||||
"signUpsTooManyWaiting": "Too many new accounts already wait for approval. Try again later.",
|
||||
"@signUpsTooManyWaiting": {
|
||||
"description": "A sign-up refused: ten new accounts wait for the operator's approval already (D19)."
|
||||
},
|
||||
|
|
@ -742,5 +742,169 @@
|
|||
"simpleLoginSectionTitle": "SimpleLogin",
|
||||
"simpleLoginSignsYouIn": "Signs you in",
|
||||
"simpleLoginAddHint": "Sign in with SimpleLogin, or with your Proton account.",
|
||||
"simpleLoginAdded": "SimpleLogin added."
|
||||
"simpleLoginAdded": "SimpleLogin added.",
|
||||
"operatorTitle": "This instance",
|
||||
"@operatorTitle": {
|
||||
"description": "The card and screen for whoever operates the instance (ADR 0021, D34)."
|
||||
},
|
||||
"operatorAccounts": "Accounts and operators",
|
||||
"@operatorAccounts": {
|
||||
"description": "The tile leading to the operator's screen."
|
||||
},
|
||||
"operatorWaitingCount": "{count, plural, =0{Nobody waits for approval} =1{1 account waits for approval} other{{count} accounts wait for approval}}",
|
||||
"@operatorWaitingCount": {
|
||||
"description": "How many accounts wait for the operator; also the badge's label.",
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"operatorWaitingTitle": "Waiting",
|
||||
"@operatorWaitingTitle": {
|
||||
"description": "The card of accounts that wait for approval, new or suspended."
|
||||
},
|
||||
"operatorNobodyWaits": "Nobody waits.",
|
||||
"@operatorNobodyWaits": {
|
||||
"description": "The waiting card, empty."
|
||||
},
|
||||
"operatorNoHandle": "No handle yet",
|
||||
"@operatorNoHandle": {
|
||||
"description": "An account without a handle, where its handle would be."
|
||||
},
|
||||
"operatorNewSince": "New, waiting since {date}",
|
||||
"@operatorNewSince": {
|
||||
"description": "A new account that waits, and since when.",
|
||||
"placeholders": {
|
||||
"date": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"operatorSuspendedSince": "Suspended since {date}",
|
||||
"@operatorSuspendedSince": {
|
||||
"description": "A suspended account, and since when.",
|
||||
"placeholders": {
|
||||
"date": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"operatorApproveNote": "Read them these four words, and approve only once they confirm these are on their screen.",
|
||||
"@operatorApproveNote": {
|
||||
"description": "Before approving: the words prove it is their account that waits (D33)."
|
||||
},
|
||||
"operatorApprove": "Approve",
|
||||
"@operatorApprove": {
|
||||
"description": "Approves a waiting account."
|
||||
},
|
||||
"operatorRefuse": "Refuse",
|
||||
"@operatorRefuse": {
|
||||
"description": "Refuses a new account: deleted."
|
||||
},
|
||||
"operatorRefuseTitle": "Refuse this account?",
|
||||
"@operatorRefuseTitle": {
|
||||
"description": "The question before refusing."
|
||||
},
|
||||
"operatorRefuseMessage": "It is deleted with everything it has. They can sign up again.",
|
||||
"@operatorRefuseMessage": {
|
||||
"description": "What refusing does."
|
||||
},
|
||||
"operatorOperatorsTitle": "Operators",
|
||||
"@operatorOperatorsTitle": {
|
||||
"description": "The card of who operates the instance."
|
||||
},
|
||||
"operatorTakeBack": "Take back",
|
||||
"@operatorTakeBack": {
|
||||
"description": "Takes back the operator's role."
|
||||
},
|
||||
"operatorTakeBackTitle": "Take back the role?",
|
||||
"@operatorTakeBackTitle": {
|
||||
"description": "The question before taking the role back."
|
||||
},
|
||||
"operatorTakeBackMessage": "They keep their account, but no longer approve, refuse or suspend accounts here.",
|
||||
"@operatorTakeBackMessage": {
|
||||
"description": "What taking the role back does."
|
||||
},
|
||||
"operatorAppoint": "Name an operator",
|
||||
"@operatorAppoint": {
|
||||
"description": "Names an account an operator, by its handle."
|
||||
},
|
||||
"operatorAppointMessage": "They approve, refuse and suspend accounts here, and name operators, as you do.",
|
||||
"@operatorAppointMessage": {
|
||||
"description": "What an operator may do."
|
||||
},
|
||||
"operatorAppointConfirm": "Name",
|
||||
"@operatorAppointConfirm": {
|
||||
"description": "Confirms naming an operator."
|
||||
},
|
||||
"operatorHandle": "Handle",
|
||||
"@operatorHandle": {
|
||||
"description": "The field for an account's handle."
|
||||
},
|
||||
"operatorFindTitle": "Find an account",
|
||||
"@operatorFindTitle": {
|
||||
"description": "The card searching accounts by the start of their handle."
|
||||
},
|
||||
"operatorFoundNone": "No account's handle starts like this.",
|
||||
"@operatorFoundNone": {
|
||||
"description": "A search that found nothing."
|
||||
},
|
||||
"operatorMadeOn": "Since {date}",
|
||||
"@operatorMadeOn": {
|
||||
"description": "When an account was made.",
|
||||
"placeholders": {
|
||||
"date": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"operatorIsOperator": "Operator",
|
||||
"@operatorIsOperator": {
|
||||
"description": "A tag: the account operates the instance."
|
||||
},
|
||||
"operatorIsWaiting": "Waiting",
|
||||
"@operatorIsWaiting": {
|
||||
"description": "A tag: the account waits for approval."
|
||||
},
|
||||
"operatorIsSuspended": "Suspended",
|
||||
"@operatorIsSuspended": {
|
||||
"description": "A tag: the account is suspended."
|
||||
},
|
||||
"operatorSuspend": "Suspend",
|
||||
"@operatorSuspend": {
|
||||
"description": "Suspends an account."
|
||||
},
|
||||
"operatorSuspendTitle": "Suspend this account?",
|
||||
"@operatorSuspendTitle": {
|
||||
"description": "The question before suspending."
|
||||
},
|
||||
"operatorSuspendMessage": "They are signed out everywhere and can't sign in until you approve them again. Nothing they have is deleted.",
|
||||
"@operatorSuspendMessage": {
|
||||
"description": "What suspending does."
|
||||
},
|
||||
"operatorMakeOperator": "Name as operator",
|
||||
"@operatorMakeOperator": {
|
||||
"description": "Names a found account an operator."
|
||||
},
|
||||
"operatorNotFound": "That account isn't there any more, or doesn't wait.",
|
||||
"@operatorNotFound": {
|
||||
"description": "Refused: no such account, or it doesn't wait."
|
||||
},
|
||||
"operatorIsOperatorProblem": "An operator can't be suspended. Take back their role first.",
|
||||
"@operatorIsOperatorProblem": {
|
||||
"description": "Refused: suspending an operator."
|
||||
},
|
||||
"operatorLastOperator": "The instance needs at least one operator.",
|
||||
"@operatorLastOperator": {
|
||||
"description": "Refused: taking back the last operator's role."
|
||||
},
|
||||
"operatorNotAllowed": "Only the instance's operators can do this.",
|
||||
"@operatorNotAllowed": {
|
||||
"description": "Refused: the person doesn't operate the instance."
|
||||
},
|
||||
"operatorFailed": "That didn't work. Try again.",
|
||||
"@operatorFailed": {
|
||||
"description": "Any other failure."
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue