Browse Source

fix(l10n): Less jargon in source strings

This removes:
- “enable” for settings
- “settings” for settings sections
- “all” when there is no obvious subset of items
- “show” and “open” for navigation actions
- “changes” for applying/discarding
- “to clipboard” when copying
- Explaining things that cannot happen
- Explaining things twice, right below each other
- Unnecessary technical jargon
- Text that sounds like marketing copy and serves no other purpose

Signed-off-by: kramo <git@kramo.page>
pull/54202/head
kramo 2 months ago
committed by Ferdinand Thiessen
parent
commit
c5d1f2f9ff
No known key found for this signature in database GPG Key ID: 45FAE7268762B400
  1. 4
      apps/federatedfilesharing/src/components/PersonalSettings.vue
  2. 2
      apps/files/src/actions/sidebarAction.spec.ts
  3. 2
      apps/files/src/actions/sidebarAction.ts
  4. 6
      apps/files/src/components/FilesListTableHeaderActions.vue
  5. 8
      apps/files/src/components/FilesNavigationSearch.vue
  6. 2
      apps/files/src/filters/TypeFilter.ts
  7. 6
      apps/files/src/utils/actionUtils.ts
  8. 2
      apps/files/src/utils/davUtils.ts
  9. 6
      apps/files/src/views/FilesList.vue
  10. 60
      apps/files/src/views/Settings.vue
  11. 4
      apps/files_reminders/src/actions/setReminderCustomAction.ts
  12. 2
      apps/files_reminders/src/components/SetCustomReminderModal.vue
  13. 4
      apps/files_sharing/src/components/NewFileRequestDialog/NewFileRequestDialogFinish.vue
  14. 7
      apps/files_sharing/src/components/SharingEntryInternal.vue
  15. 2
      apps/files_sharing/src/components/SharingEntryLink.vue
  16. 2
      apps/files_sharing/src/components/SharingInput.vue
  17. 2
      apps/files_sharing/src/files_actions/sharingStatusAction.ts
  18. 21
      apps/files_sharing/src/views/SharingTab.vue
  19. 4
      apps/systemtags/src/components/SystemTagPicker.vue
  20. 2
      core/src/components/PublicPageMenu/PublicPageMenuLinkEntry.vue
  21. 2
      cypress/e2e/files_sharing/share-status-action.cy.ts

4
apps/federatedfilesharing/src/components/PersonalSettings.vue

@ -156,14 +156,14 @@ export default {
</a>`
},
copyLinkTooltip() {
return this.isCopied ? t('federatedfilesharing', 'Cloud ID copied to the clipboard') : t('federatedfilesharing', 'Copy to clipboard')
return this.isCopied ? t('federatedfilesharing', 'Cloud ID copied') : t('federatedfilesharing', 'Copy')
},
},
methods: {
async copyCloudId(): Promise<void> {
try {
await navigator.clipboard.writeText(this.cloudId)
showSuccess(t('federatedfilesharing', 'Cloud ID copied to the clipboard'))
showSuccess(t('federatedfilesharing', 'Cloud ID copied'))
} catch (e) {
// no secure context or really old browser - need a fallback
window.prompt(t('federatedfilesharing', 'Clipboard not available. Please copy the cloud ID manually.'), this.reference)

2
apps/files/src/actions/sidebarAction.spec.ts

@ -17,7 +17,7 @@ describe('Open sidebar action conditions tests', () => {
test('Default values', () => {
expect(action).toBeInstanceOf(FileAction)
expect(action.id).toBe('details')
expect(action.displayName([], view)).toBe('Open details')
expect(action.displayName([], view)).toBe('Details')
expect(action.iconSvgInline([], view)).toMatch(/<svg.+<\/svg>/)
expect(action.default).toBeUndefined()
expect(action.order).toBe(-50)

2
apps/files/src/actions/sidebarAction.ts

@ -16,7 +16,7 @@ export const ACTION_DETAILS = 'details'
export const action = new FileAction({
id: ACTION_DETAILS,
displayName: () => t('files', 'Open details'),
displayName: () => t('files', 'Details'),
iconSvgInline: () => InformationSvg,
// Sidebar currently supports user folder only, /files/USER

6
apps/files/src/components/FilesListTableHeaderActions.vue

@ -305,16 +305,16 @@ export default defineComponent({
return
}
showError(this.t('files', '"{displayName}" failed on some elements', { displayName }))
showError(this.t('files', '{displayName}: failed on some elements', { displayName }))
return
}
// Show success message and clear selection
showSuccess(this.t('files', '"{displayName}" batch action executed successfully', { displayName }))
showSuccess(this.t('files', '{displayName}: done', { displayName }))
this.selectionStore.reset()
} catch (e) {
logger.error('Error while executing action', { action, e })
showError(this.t('files', '"{displayName}" action failed', { displayName }))
showError(this.t('files', '{displayName}: failed', { displayName }))
} finally {
// Remove loading markers
this.loading = null

8
apps/files/src/components/FilesNavigationSearch.vue

@ -55,9 +55,9 @@ const isSearchView = computed(() => currentView.value.id === VIEW_ID)
*/
const searchLabel = computed(() => {
if (searchStore.scope === 'globally') {
return t('files', 'Search globally by filename …')
return t('files', 'Search everywhere …')
}
return t('files', 'Search here by filename …')
return t('files', 'Search here …')
})
</script>
@ -72,13 +72,13 @@ const searchLabel = computed(() => {
<template #icon>
<NcIconSvgWrapper :path="mdiMagnify" />
</template>
{{ t('files', 'Filter and search from this location') }}
{{ t('files', 'Search here') }}
</NcActionButton>
<NcActionButton close-after-click @click="searchStore.scope = 'globally'">
<template #icon>
<NcIconSvgWrapper :path="mdiSearchWeb" />
</template>
{{ t('files', 'Search globally') }}
{{ t('files', 'Search everywhere') }}
</NcActionButton>
</NcActions>
</template>

2
apps/files/src/filters/TypeFilter.ts

@ -73,7 +73,7 @@ const getTypePresets = async () => [
{
id: 'image',
// TRANSLATORS: This is for filtering files, e.g. PNG or JPEG, so photos, drawings, or images in general
label: t('files', 'Photos and images'),
label: t('files', 'Images'),
icon: svgImage,
mime: ['image'],
},

6
apps/files/src/utils/actionUtils.ts

@ -59,13 +59,13 @@ export const executeAction = async (action: FileAction) => {
}
if (success) {
showSuccess(t('files', '"{displayName}" action executed successfully', { displayName }))
showSuccess(t('files', '{displayName}: done', { displayName }))
return
}
showError(t('files', '"{displayName}" action failed', { displayName }))
showError(t('files', '{displayName}: failed', { displayName }))
} catch (error) {
logger.error('Error while executing action', { action, error })
showError(t('files', '"{displayName}" action failed', { displayName }))
showError(t('files', '{displayName}: failed', { displayName }))
} finally {
// Reset the loading marker
Vue.set(currentNode, 'status', undefined)

2
apps/files/src/utils/davUtils.ts

@ -29,7 +29,7 @@ export function humanizeWebDAVError(error: unknown) {
} else if (status === 403) {
return t('files', 'This operation is forbidden')
} else if (status === 500) {
return t('files', 'This directory is unavailable, please check the logs or contact the administrator')
return t('files', 'This folder is unavailable, please try again later or contact the administration')
} else if (status === 503) {
return t('files', 'Storage is temporarily not available')
}

6
apps/files/src/views/FilesList.vue

@ -816,13 +816,13 @@ export default defineComponent({
}
if (success) {
showSuccess(t('files', '"{displayName}" action executed successfully', { displayName }))
showSuccess(t('files', '{displayName}: done', { displayName }))
return
}
showError(t('files', '"{displayName}" action failed', { displayName }))
showError(t('files', '{displayName}: failed', { displayName }))
} catch (error) {
logger.error('Error while executing action', { action, error })
showError(t('files', '"{displayName}" action failed', { displayName }))
showError(t('files', '{displayName}: failed', { displayName }))
} finally {
this.loadingAction = null
}

60
apps/files/src/views/Settings.vue

@ -8,7 +8,7 @@
:name="t('files', 'Files settings')"
@update:open="onClose">
<!-- Settings API-->
<NcAppSettingsSection id="settings" :name="t('files', 'Files settings')">
<NcAppSettingsSection id="settings" :name="t('files', 'General')">
<fieldset class="files-settings__default-view"
data-cy-files-settings-setting="default_view">
<legend>
@ -42,12 +42,12 @@
<NcCheckboxRadioSwitch data-cy-files-settings-setting="folder_tree"
:checked="userConfig.folder_tree"
@update:checked="setConfig('folder_tree', $event)">
{{ t('files', 'Enable folder tree') }}
{{ t('files', 'Folder tree') }}
</NcCheckboxRadioSwitch>
</NcAppSettingsSection>
<!-- Visual settings -->
<NcAppSettingsSection id="settings" :name="t('files', 'Visual settings')">
<!-- Appearance -->
<NcAppSettingsSection id="settings" :name="t('files', 'Appearance')">
<NcCheckboxRadioSwitch data-cy-files-settings-setting="show_hidden"
:checked="userConfig.show_hidden"
@update:checked="setConfig('show_hidden', $event)">
@ -58,16 +58,16 @@
@update:checked="setConfig('show_mime_column', $event)">
{{ t('files', 'Show file type column') }}
</NcCheckboxRadioSwitch>
<NcCheckboxRadioSwitch data-cy-files-settings-setting="show_files_extensions"
:checked="userConfig.show_files_extensions"
@update:checked="setConfig('show_files_extensions', $event)">
{{ t('files', 'Show file extensions') }}
</NcCheckboxRadioSwitch>
<NcCheckboxRadioSwitch data-cy-files-settings-setting="crop_image_previews"
:checked="userConfig.crop_image_previews"
@update:checked="setConfig('crop_image_previews', $event)">
{{ t('files', 'Crop image previews') }}
</NcCheckboxRadioSwitch>
<NcCheckboxRadioSwitch data-cy-files-settings-setting="show_files_extensions"
:checked="userConfig.show_files_extensions"
@update:checked="setConfig('show_files_extensions', $event)">
{{ t('files', 'Show files extensions') }}
</NcCheckboxRadioSwitch>
</NcAppSettingsSection>
<!-- Settings API-->
@ -85,7 +85,7 @@
:label="t('files', 'WebDAV URL')"
:show-trailing-button="true"
:success="webdavUrlCopied"
:trailing-button-label="t('files', 'Copy to clipboard')"
:trailing-button-label="t('files', 'Copy')"
:value="webdavUrl"
class="webdav-url-input"
readonly="readonly"
@ -101,7 +101,7 @@
:href="webdavDocs"
target="_blank"
rel="noreferrer noopener">
{{ t('files', 'Use this address to access your Files via WebDAV.') }}
{{ t('files', 'How to access files using WebDAV') }}
</a>
</em>
<br>
@ -113,22 +113,20 @@
</NcAppSettingsSection>
<NcAppSettingsSection id="warning" :name="t('files', 'Warnings')">
<em>{{ t('files', 'Prevent warning dialogs from open or reenable them.') }}</em>
<NcCheckboxRadioSwitch type="switch"
:checked="userConfig.show_dialog_file_extension"
@update:checked="setConfig('show_dialog_file_extension', $event)">
{{ t('files', 'Show a warning dialog when changing a file extension.') }}
{{ t('files', 'Warn before changing a file extension') }}
</NcCheckboxRadioSwitch>
<NcCheckboxRadioSwitch type="switch"
:checked="userConfig.show_dialog_deletion"
@update:checked="setConfig('show_dialog_deletion', $event)">
{{ t('files', 'Show a warning dialog when deleting files.') }}
{{ t('files', 'Warn before deleting files') }}
</NcCheckboxRadioSwitch>
</NcAppSettingsSection>
<NcAppSettingsSection id="shortcuts"
:name="t('files', 'Keyboard shortcuts')">
<em>{{ t('files', 'Speed up your Files experience with these quick shortcuts.') }}</em>
<h3>{{ t('files', 'Actions') }}</h3>
<dl>
@ -137,7 +135,7 @@
<kbd>a</kbd>
</dt>
<dd class="shortcut-description">
{{ t('files', 'Open the actions menu for a file') }}
{{ t('files', 'File actions') }}
</dd>
</div>
<div>
@ -145,7 +143,7 @@
<kbd>F2</kbd>
</dt>
<dd class="shortcut-description">
{{ t('files', 'Rename a file') }}
{{ t('files', 'Rename') }}
</dd>
</div>
<div>
@ -153,7 +151,7 @@
<kbd>Del</kbd>
</dt>
<dd class="shortcut-description">
{{ t('files', 'Delete a file') }}
{{ t('files', 'Delete') }}
</dd>
</div>
<div>
@ -161,7 +159,7 @@
<kbd>s</kbd>
</dt>
<dd class="shortcut-description">
{{ t('files', 'Favorite or remove a file from favorites') }}
{{ t('files', 'Add or remove favorite') }}
</dd>
</div>
<div v-if="isSystemtagsEnabled">
@ -169,7 +167,7 @@
<kbd>t</kbd>
</dt>
<dd class="shortcut-description">
{{ t('files', 'Manage tags for a file') }}
{{ t('files', 'Manage tags') }}
</dd>
</div>
</dl>
@ -189,7 +187,7 @@
<kbd>ESC</kbd>
</dt>
<dd class="shortcut-description">
{{ t('files', 'Deselect all files') }}
{{ t('files', 'Deselect all') }}
</dd>
</div>
<div>
@ -197,7 +195,7 @@
<kbd>Ctrl</kbd> + <kbd>Space</kbd>
</dt>
<dd class="shortcut-description">
{{ t('files', 'Select or deselect a file') }}
{{ t('files', 'Select or deselect') }}
</dd>
</div>
<div>
@ -205,7 +203,7 @@
<kbd>Ctrl</kbd> + <kbd>Shift</kbd> <span>+ <kbd>Space</kbd></span>
</dt>
<dd class="shortcut-description">
{{ t('files', 'Select a range of files') }}
{{ t('files', 'Select a range') }}
</dd>
</div>
</dl>
@ -217,7 +215,7 @@
<kbd>Alt</kbd> + <kbd></kbd>
</dt>
<dd class="shortcut-description">
{{ t('files', 'Navigate to the parent folder') }}
{{ t('files', 'Go to parent folder') }}
</dd>
</div>
<div>
@ -225,7 +223,7 @@
<kbd></kbd>
</dt>
<dd class="shortcut-description">
{{ t('files', 'Navigate to the file above') }}
{{ t('files', 'Go to file above') }}
</dd>
</div>
<div>
@ -233,7 +231,7 @@
<kbd></kbd>
</dt>
<dd class="shortcut-description">
{{ t('files', 'Navigate to the file below') }}
{{ t('files', 'Go to file below') }}
</dd>
</div>
<div>
@ -241,7 +239,7 @@
<kbd></kbd>
</dt>
<dd class="shortcut-description">
{{ t('files', 'Navigate to the file on the left (in grid mode)') }}
{{ t('files', 'Go left in grid') }}
</dd>
</div>
<div>
@ -249,7 +247,7 @@
<kbd></kbd>
</dt>
<dd class="shortcut-description">
{{ t('files', 'Navigate to the file on the right (in grid mode)') }}
{{ t('files', 'Go right in grid') }}
</dd>
</div>
</dl>
@ -261,7 +259,7 @@
<kbd>V</kbd>
</dt>
<dd class="shortcut-description">
{{ t('files', 'Toggle the grid view') }}
{{ t('files', 'Toggle grid view') }}
</dd>
</div>
<div>
@ -269,7 +267,7 @@
<kbd>D</kbd>
</dt>
<dd class="shortcut-description">
{{ t('files', 'Open the sidebar for a file') }}
{{ t('files', 'Open file sidebar') }}
</dd>
</div>
<div>
@ -400,7 +398,7 @@ export default {
await navigator.clipboard.writeText(this.webdavUrl)
this.webdavUrlCopied = true
showSuccess(t('files', 'WebDAV URL copied to clipboard'))
showSuccess(t('files', 'WebDAV URL copied'))
setTimeout(() => {
this.webdavUrlCopied = false
}, 5000)

4
apps/files_reminders/src/actions/setReminderCustomAction.ts

@ -14,8 +14,8 @@ import { pickCustomDate } from '../services/customPicker'
export const action = new FileAction({
id: 'set-reminder-custom',
displayName: () => t('files_reminders', 'Set custom reminder'),
title: () => t('files_reminders', 'Set reminder at custom date & time'),
displayName: () => t('files_reminders', 'Custom reminder'),
title: () => t('files_reminders', 'Reminder at custom date & time'),
iconSvgInline: () => CalendarClockSvg,
enabled: (nodes: Node[], view: View) => {

2
apps/files_reminders/src/components/SetCustomReminderModal.vue

@ -106,7 +106,7 @@ export default Vue.extend({
},
label(): string {
return t('files_reminders', 'Set reminder at custom date & time')
return t('files_reminders', 'Reminder at custom date & time')
},
clearAriaLabel(): string {

4
apps/files_sharing/src/components/NewFileRequestDialog/NewFileRequestDialogFinish.vue

@ -16,7 +16,7 @@
:label="t('files_sharing', 'Share link')"
:readonly="true"
:show-trailing-button="true"
:trailing-button-label="t('files_sharing', 'Copy to clipboard')"
:trailing-button-label="t('files_sharing', 'Copy')"
data-cy-file-request-dialog-fieldset="link"
@click="copyShareLink"
@trailing-button-click="copyShareLink">
@ -140,7 +140,7 @@ export default defineComponent({
await navigator.clipboard.writeText(this.shareLink)
showSuccess(t('files_sharing', 'Link copied to clipboard'))
showSuccess(t('files_sharing', 'Link copied'))
this.isCopied = true
event.target?.select?.()

7
apps/files_sharing/src/components/SharingEntryInternal.vue

@ -83,14 +83,11 @@ export default {
}
return t('files_sharing', 'Cannot copy, please copy the link manually')
}
return t('files_sharing', 'Copy internal link to clipboard')
return t('files_sharing', 'Copy internal link')
},
internalLinkSubtitle() {
if (this.fileInfo.type === 'dir') {
return t('files_sharing', 'Only works for people with access to this folder')
}
return t('files_sharing', 'Only works for people with access to this file')
return t('files_sharing', 'For people who already have access')
},
},

2
apps/files_sharing/src/components/SharingEntryLink.vue

@ -550,7 +550,7 @@ export default {
}
return t('files_sharing', 'Cannot copy, please copy the link manually')
}
return t('files_sharing', 'Copy public link of "{title}" to clipboard', { title: this.title })
return t('files_sharing', 'Copy public link of "{title}"', { title: this.title })
},
/**

2
apps/files_sharing/src/components/SharingInput.vue

@ -264,7 +264,7 @@ export default {
lookupEntry.push({
id: 'global-lookup',
isNoUser: true,
displayName: t('files_sharing', 'Search globally'),
displayName: t('files_sharing', 'Search everywhere'),
lookup: true,
})
}

2
apps/files_sharing/src/files_actions/sharingStatusAction.ts

@ -53,7 +53,7 @@ export const action = new FileAction({
const sharees = node.attributes.sharees?.sharee as { id: string, 'display-name': string, type: ShareType }[] | undefined
if (!sharees) {
// No sharees so just show the default message to create a new share
return t('files_sharing', 'Show sharing options')
return t('files_sharing', 'Sharing options')
}
const sharee = [sharees].flat()[0] // the property is sometimes weirdly normalized, so we need to compensate

21
apps/files_sharing/src/views/SharingTab.vue

@ -230,9 +230,9 @@ export default {
shareDetailsData: {},
returnFocusElement: null,
internalSharesHelpText: t('files_sharing', 'Use this method to share files with individuals or teams within your organization. If the recipient already has access to the share but cannot locate it, you can send them the internal share link for easy access.'),
externalSharesHelpText: t('files_sharing', 'Use this method to share files with individuals or organizations outside your organization. Files and folders can be shared via public share links and email addresses. You can also share to other Nextcloud accounts hosted on different instances using their federated cloud ID.'),
additionalSharesHelpText: t('files_sharing', 'Shares that are not part of the internal or external shares. This can be shares from apps or other sources.'),
internalSharesHelpText: t('files_sharing', 'Share files within your organization. Recipients who can already view the file can also use this link for easy access.'),
externalSharesHelpText: t('files_sharing', 'Share files with others outside your organization via public links and email addresses. You can also share to Nextcloud accounts on other instances using their federated cloud ID.'),
additionalSharesHelpText: t('files_sharing', 'Shares from apps or other sources which are not included in internal or external shares.'),
}
},
@ -269,17 +269,22 @@ export default {
internalShareInputPlaceholder() {
return this.config.showFederatedSharesAsInternal && this.config.isFederationEnabled
? t('files_sharing', 'Share with accounts, teams, federated cloud IDs')
: t('files_sharing', 'Share with accounts and teams')
// TRANSLATORS: Type as in with a keyboard
? t('files_sharing', 'Type names, teams, federated cloud IDs')
// TRANSLATORS: Type as in with a keyboard
: t('files_sharing', 'Type names or teams')
},
externalShareInputPlaceholder() {
if (!this.isLinkSharingAllowed) {
return this.config.isFederationEnabled ? t('files_sharing', 'Federated cloud ID') : ''
// TRANSLATORS: Type as in with a keyboard
return this.config.isFederationEnabled ? t('files_sharing', 'Type a federated cloud ID') : ''
}
return !this.config.showFederatedSharesAsInternal && !this.config.isFederationEnabled
? t('files_sharing', 'Email')
: t('files_sharing', 'Email, federated cloud ID')
// TRANSLATORS: Type as in with a keyboard
? t('files_sharing', 'Type an email')
// TRANSLATORS: Type as in with a keyboard
: t('files_sharing', 'Type an email or federated cloud ID')
},
},
methods: {

4
apps/systemtags/src/components/SystemTagPicker.vue

@ -95,7 +95,7 @@
<!-- Note -->
<div class="systemtags-picker__note">
<NcNoteCard v-if="!hasChanges" type="info">
{{ canEditOrCreateTag ? t('systemtags', 'Select or create tags to apply to all selected files'): t('systemtags', 'Select tags to apply to all selected files') }}
{{ t('systemtags', 'Choose tags for the selected files') }}
</NcNoteCard>
<NcNoteCard v-else type="info">
<span v-html="statusMessage" />
@ -113,7 +113,7 @@
<NcButton :disabled="!hasChanges || status !== Status.BASE"
data-cy-systemtags-picker-button-submit
@click="onSubmit">
{{ t('systemtags', 'Apply changes') }}
{{ t('systemtags', 'Apply') }}
</NcButton>
</template>

2
core/src/components/PublicPageMenu/PublicPageMenuLinkEntry.vue

@ -33,7 +33,7 @@ const emit = defineEmits<{
async function copyLink() {
try {
await window.navigator.clipboard.writeText(props.href)
showSuccess(t('core', 'Direct link copied to clipboard'))
showSuccess(t('core', 'Direct link copied'))
} catch {
// No secure context -> fallback to dialog
window.prompt(t('core', 'Please copy the link manually:'), props.href)

2
cypress/e2e/files_sharing/share-status-action.cy.ts

@ -40,7 +40,7 @@ describe('files_sharing: Sharing status action', { testIsolation: true }, () =>
getRowForFile('folder')
.should('be.visible')
.find('[data-cy-files-list-row-actions]')
.findByRole('button', { name: /Show sharing options/ })
.findByRole('button', { name: /Sharing options/ })
.should('be.visible')
.click()

Loading…
Cancel
Save