APP_NAME renames an instance, but only the sign-in page, the title bar and
a few headings used it. Two dozen sentences wrote "ihasmail" into
themselves, so a renamed instance still told people to keep an ihasmail
tab open and offered to open mail links "in ihasmail".
Those sentences now take the name as {app}, which also lets a translator
put it where their language wants it. brand.ts grew useAppName() for
components and currentAppName() for the few places that build strings
outside React.
Left as they are: the Files folder "ihasmail", the Sieve script
"ihasmail" and ihasmail.org. Those name things a person can go and look
at, and renaming them would rename real data.
All nine catalogues keep their translations: the name inside each one
became the placeholder. Three of the strings had no translation before
and still fall back to English.
A test walks the sources and the catalogues so a new sentence can't
hard-code the name again.
48 lines
1.8 KiB
TypeScript
48 lines
1.8 KiB
TypeScript
import { shareSummary, type SharedContent } from "@/lib/shareTarget";
|
|
import { useAppName } from "@/lib/brand";
|
|
import { confirmDialog } from "@/ui/dialog";
|
|
import { t } from "@/lib/i18n";
|
|
|
|
/**
|
|
* Ask before a share becomes a message.
|
|
*
|
|
* The share address takes a plain form POST, so any website can send one, and
|
|
* the page cannot tell that from a share the reader made. Nothing would be
|
|
* sent without them pressing Send, but a composer that appears full of
|
|
* somebody else's text and files is still something to be asked about first.
|
|
*/
|
|
export async function offerShare(share: SharedContent, open: (share: SharedContent) => unknown): Promise<boolean> {
|
|
const yes = await confirmDialog({
|
|
title: t("Start a new message with what was shared?"),
|
|
message: <ShareSummary share={share} />,
|
|
confirmLabel: t("Start a message"),
|
|
cancelLabel: t("Discard"),
|
|
});
|
|
if (yes) open(share);
|
|
return yes;
|
|
}
|
|
|
|
/** What arrived, so the reader can tell whether it is theirs. */
|
|
function ShareSummary({ share }: { share: SharedContent }) {
|
|
const appName = useAppName();
|
|
const { title, preview, files } = shareSummary(share);
|
|
return (
|
|
<div>
|
|
{(title || preview) && (
|
|
<blockquote className="share-summary notranslate" translate="no">
|
|
{title && <strong>{title}</strong>}
|
|
{title && preview && <br />}
|
|
{preview}
|
|
</blockquote>
|
|
)}
|
|
{files.length > 0 && (
|
|
<ul className="share-summary-files notranslate" translate="no">
|
|
{files.slice(0, 5).map((name, i) => <li key={`${name}-${i}`}>{name}</li>)}
|
|
{files.length > 5 && <li>…</li>}
|
|
</ul>
|
|
)}
|
|
<p>{t("Something was shared with {app}. Nothing is sent until you choose Send. If you didn't just share this, discard it.", { app: appName })}</p>
|
|
</div>
|
|
);
|
|
}
|