Skip to content

Commit

Permalink
fix: translate remaining strings
Browse files Browse the repository at this point in the history
  • Loading branch information
stipsan committed Oct 21, 2024
1 parent c47b0b6 commit caac940
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 153 deletions.
33 changes: 21 additions & 12 deletions packages/presentation/src/i18n/resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,23 +93,32 @@ export default {
'share-url.clipboard.status_success': 'The URL is copied to the clipboard',
/** The status of the clipboard operation when copying a URL */
'share-url.clipboard.status_unsupported': 'Clipboard not supported',
/** The share URL menu item text for copying a link */
'share-url.menu-item.copy.text': 'Copy link',
/** The share URL menu item text for configuring a public share link */
'share-url.menu-item.share.text': 'Share link',
/** The share URL menu item text for opening a preview window */
'share-url.menu-item.open.text': 'Open preview',
/** The dialog header for the share url dialog */
'share-url.dialog.header': 'Configure share link',
/** Action in the share url dialog that creates a URL that can be used to preview the current pathname */
'share-url.dialog.action.enable-sharing': 'Enable sharing to those who have the link',
/** Disables sharing access to those who have the link */
'share-url.dialog.action.disable-sharing': 'Disable sharing',
/** Error toast that notifies that URL Preview Secrets can't be generated as the user lacks ACL grants */
'preview-url-secret.missing-grants':
"You don't have permission to create URL Preview Secrets. This will likely cause the preview to fail loading.",
/** The `aria-label` for the button that opens the share menu */
'preview-frame.share-button.aria-label': 'Share this preview',
/** The tooltip for the button that opens the share menu */
'preview-frame.share-button.tooltip': 'Share this preview',
/** The <title> for the QR Code SVG that shows a link to the current preview */
'share-preview-menu.qr-code.title': 'A QR Code which encodes the URL: {{url}}',
/** Error message toast that shows the current user does not have permission to toggle sharing of the current preview */
'share-preview-menu.error_toggle-sharing':
"You don't have permission to toggle sharing of this preview",
/** The text shown on the sharing toggle tooltip when sharing is enabled */
'share-preview-menu.toggle-button.tooltip_disable': 'Disable sharing',
/** The text shown on the sharing toggle tooltip when sharing is disabled */
'share-preview-menu.toggle-button.tooltip_enable': 'Enable sharing',
/** The first line of the label that renders next to the sharing toggle, it renders on two rows */
'share-preview-menu.toggle-button.label_first-line': 'Share this preview',
/** The second line of the label that renders next to the sharing toggle, it renders on two rows */
'share-preview-menu.toggle-button.label_second-line': 'with anyone who has the link',
/** Placeholder message for the QR Code SVG when sharing is yet to be enabled */
'share-preview-menu.qr-code.placeholder': 'QR code will appear here',
/** The text show below the QR Code SVG, with instructions on how to use it */
'share-preview-menu.qr-code.instructions': 'Scan the QR Code to open the preview on your phone.',
/** Menu item in the share preview menu that allows copying the current preview URL, if sharing is enabled */
'share-preview-menu.copy-url.text': 'Copy preview link',
/** Fallback message shown when the current user is not permitted to share previews */
'share-preview-menu.error_missing-grants': "You don't have permission to share previews. ",
}
147 changes: 29 additions & 118 deletions packages/presentation/src/preview/QRCodeSVG.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {Ecc, QrCode, QrSegment} from './qrcodegen'
type Modules = Array<Array<boolean>>
type Excavation = {x: number; y: number; w: number; h: number}
type ErrorCorrectionLevel = 'L' | 'M' | 'Q' | 'H'
type CrossOrigin = 'anonymous' | 'use-credentials' | '' | undefined

type ERROR_LEVEL_MAPPED_TYPE = {
[index in ErrorCorrectionLevel]: Ecc
Expand All @@ -25,51 +24,6 @@ const ERROR_LEVEL_MAP: ERROR_LEVEL_MAPPED_TYPE = {
H: Ecc.HIGH,
} as const

type ImageSettings = {
/**
* The URI of the embedded image.
*/
src: string
/**
* The height, in pixels, of the image.
*/
height: number
/**
* The width, in pixels, of the image.
*/
width: number
/**
* Whether or not to "excavate" the modules around the embedded image. This
* means that any modules the embedded image overlaps will use the background
* color.
*/
excavate: boolean
/**
* The horiztonal offset of the embedded image, starting from the top left corner.
* Will center if not specified.
*/
x?: number
/**
* The vertical offset of the embedded image, starting from the top left corner.
* Will center if not specified.
*/
y?: number
/**
* The opacity of the embedded image in the range of 0-1.
* @defaultValue 1
*/
opacity?: number
/**
* The cross-origin value to use when loading the image. This is used to
* ensure compatibility with CORS, particularly when extracting image data
* from QRCodeCanvas.
* Note: `undefined` is treated differently than the seemingly equivalent
* empty string. This is intended to align with HTML behavior where omitting
* the attribute behaves differently than the empty string.
*/
crossOrigin?: CrossOrigin
}

type QRProps = {
/**
* The value to encode into the QR Code.
Expand All @@ -87,11 +41,9 @@ type QRProps = {
*/
level?: ErrorCorrectionLevel
/**
* The foregtound color used to render the QR Code.
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/color_value
* @defaultValue #000000
*/
fgColor?: string
color?: string
/**
* The title to assign to the QR Code. Used for accessibility reasons.
*/
Expand All @@ -104,8 +56,7 @@ type QRProps = {
* @defaultValue 1
*/
minVersion?: number
imageSize: number
imageExcavate: boolean
logoSize?: number
}

const DEFAULT_SIZE = 128
Expand All @@ -117,12 +68,6 @@ const DEFAULT_MINVERSION = 1
const SPEC_MARGIN_SIZE = 4
const DEFAULT_MARGIN_SIZE = 0

// This is *very* rough estimate of max amount of QRCode allowed to be covered.
// It is "wrong" in a lot of ways (area is a terrible way to estimate, it
// really should be number of modules covered), but if for some reason we don't
// get an explicit height or width, I'd rather default to something than throw.
const DEFAULT_IMG_SCALE = 0.1

function generatePath(modules: Modules, margin: number = 0): string {
const ops: Array<string> = []
modules.forEach(function (row, y) {
Expand Down Expand Up @@ -181,40 +126,31 @@ function getImageSettings(
cells: Modules,
size: number,
margin: number,
imageSettings?: ImageSettings,
logoSize?: number,
): null | {
x: number
y: number
h: number
w: number
excavation: Excavation | null
opacity: number
crossOrigin: CrossOrigin
} {
if (imageSettings == null) {
if (!logoSize) {
return null
}
const numCells = cells.length + margin * 2
const defaultSize = Math.floor(size * DEFAULT_IMG_SCALE)
const scale = numCells / size
const w = (imageSettings.width || defaultSize) * scale
const h = (imageSettings.height || defaultSize) * scale
const x = imageSettings.x == null ? cells.length / 2 - w / 2 : imageSettings.x * scale
const y = imageSettings.y == null ? cells.length / 2 - h / 2 : imageSettings.y * scale
const opacity = imageSettings.opacity == null ? 1 : imageSettings.opacity

let excavation = null
if (imageSettings.excavate) {
const floorX = Math.floor(x)
const floorY = Math.floor(y)
const ceilW = Math.ceil(w + x - floorX)
const ceilH = Math.ceil(h + y - floorY)
excavation = {x: floorX, y: floorY, w: ceilW, h: ceilH}
}
const w = logoSize * scale
const h = logoSize * scale
const x = cells.length / 2 - w / 2
const y = cells.length / 2 - h / 2

const crossOrigin = imageSettings.crossOrigin
const floorX = Math.floor(x)
const floorY = Math.floor(y)
const ceilW = Math.ceil(w + x - floorX)
const ceilH = Math.ceil(h + y - floorY)
const excavation = {x: floorX, y: floorY, w: ceilW, h: ceilH}

return {x, y, h, w, excavation, opacity, crossOrigin}
return {x, y, h, w, excavation}
}

function getMarginSize(includeMargin: boolean, marginSize?: number): number {
Expand All @@ -230,15 +166,15 @@ function useQRCode({
minVersion,
includeMargin,
marginSize,
imageSettings,
logoSize,
size,
}: {
value: string
level: ErrorCorrectionLevel
minVersion: number
includeMargin: boolean
marginSize?: number
imageSettings?: ImageSettings
logoSize?: number
size: number
}) {
const qrcode = useMemo(() => {
Expand All @@ -251,14 +187,14 @@ function useQRCode({

const margin = getMarginSize(includeMargin, marginSize)
const numCells = cells.length + margin * 2
const calculatedImageSettings = getImageSettings(cells, size, margin, imageSettings)
const calculatedImageSettings = getImageSettings(cells, size, margin, logoSize)
return {
cells,
margin,
numCells,
calculatedImageSettings,
}
}, [qrcode, size, imageSettings, includeMargin, marginSize])
}, [qrcode, size, logoSize, includeMargin, marginSize])

return {
qrcode,
Expand All @@ -274,54 +210,30 @@ function QRCodeSVGComponent(props: QRProps) {
value,
size = DEFAULT_SIZE,
level = DEFAULT_LEVEL,
fgColor = DEFAULT_FGCOLOR,
color: color = DEFAULT_FGCOLOR,
minVersion = DEFAULT_MINVERSION,
title,
imageExcavate,
imageSize,
logoSize,
} = props
const marginSize: number | undefined = undefined

const imageSettings = useMemo(
() => ({
src: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg==',
height: imageSize,
width: imageSize,
excavate: imageExcavate,
}),
[imageExcavate, imageSize],
)
const {margin, cells, numCells, calculatedImageSettings} = useQRCode({
value,
level,
minVersion,
includeMargin: DEFAULT_INCLUDEMARGIN,
marginSize,
imageSettings,
logoSize,
size,
})

let cellsToDraw = cells
let image = null
if (imageSettings != null && calculatedImageSettings != null) {
if (calculatedImageSettings.excavation != null) {
cellsToDraw = excavateModules(cells, calculatedImageSettings.excavation)
}

image = (
<image
href={imageSettings.src}
height={calculatedImageSettings.h}
width={calculatedImageSettings.w}
x={calculatedImageSettings.x + margin}
y={calculatedImageSettings.y + margin}
preserveAspectRatio="none"
opacity={calculatedImageSettings.opacity}
// Note: specified here always, but undefined will result in no attribute.
crossOrigin={calculatedImageSettings.crossOrigin}
/>
)
}
const cellsToDraw = useMemo(
() =>
logoSize && calculatedImageSettings?.excavation
? excavateModules(cells, calculatedImageSettings.excavation)
: cells,
[calculatedImageSettings?.excavation, cells, logoSize],
)

// Drawing strategy: instead of a rect per module, we're going to create a
// single path for the dark modules and layer that on top of a light rect,
Expand All @@ -335,14 +247,13 @@ function QRCodeSVGComponent(props: QRProps) {
<svg height={size} width={size} viewBox={`0 0 ${numCells} ${numCells}`} role="img">
{!!title && <title>{title}</title>}
<motion.path
fill={fgColor}
fill={color}
d={fgPath}
shapeRendering="crispEdges"
initial={{opacity: 0}}
animate={{opacity: 2}}
exit={{opacity: -1}}
/>
{image}
</svg>
)
}
Expand Down
Loading

0 comments on commit caac940

Please sign in to comment.