Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/workflows/l10n.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: L10n
on: pull_request

jobs:
l10n-extract-check:
runs-on: ubuntu-latest
name: Pot check

steps:
- uses: actions/checkout@master

- name: Set up Node
uses: actions/setup-node@v1
with:
node-version: 12.x

- name: npm install
run: npm ci

- name: extract l10n files
run: npm run l10n:extract

- name: Check l10n file changes
run: bash -c "[[ ! \"`git status --porcelain l10n`\" ]] || ( echo 'Uncommited l10n changes. Run \`npm run l10n:extract\`.' && exit 1 )"
33 changes: 33 additions & 0 deletions .github/workflows/node.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Node

on:
pull_request:
push:
branches:
- master
- stable*

jobs:
build:
runs-on: ubuntu-latest

strategy:
matrix:
node-versions: [12.x]

name: node${{ matrix.node-versions }}
steps:
- uses: actions/checkout@v2

- name: Set up node ${{ matrix.node-versions }}
uses: actions/setup-node@v1
with:
node-versions: ${{ matrix.node-versions }}

- name: Install dependencies & build
run: |
npm ci
npm run build --if-present

- name: Build docs
run: npm run build:doc
24 changes: 24 additions & 0 deletions .github/workflows/transifex.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Transifex
on: pull_request

jobs:
approve:
runs-on: ubuntu-latest
name: Approve
steps:
- uses: hmarr/auto-approve-action@v2.0.0
if: github.actor == 'Transifex-localization-platform[bot]' || github.actor == 'transifex-integration[bot]'
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"

automerge:
runs-on: ubuntu-latest
name: Auto-merge
steps:
- uses: pascalgn/automerge-action@v0.8.4
if: github.actor == 'Transifex-localization-platform[bot]' || github.actor == 'transifex-integration[bot]'
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
MERGE_LABELS: ""
MERGE_RETRIES: 6
MERGE_RETRY_SLEEP: 30000
17 changes: 0 additions & 17 deletions .travis.yml

This file was deleted.

23 changes: 23 additions & 0 deletions build/extract-l10n.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const { GettextExtractor, JsExtractors } = require('gettext-extractor');

let extractor = new GettextExtractor();

extractor
.createJsParser([
JsExtractors.callExpression('t', {
arguments: {
text: 0,
}
}),
JsExtractors.callExpression('n', {
arguments: {
text: 1,
textPlural: 2,
}
}),
])
.parseFilesGlob('./lib/**/*.@(ts|js|vue)');

extractor.savePotFile('./l10n/messages.pot');

extractor.printStats();
20 changes: 20 additions & 0 deletions l10n/fr.pot
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#
# Translators:
# Brendan Abolivier <transifex@brendanabolivier.com>, 2020
# gud bes <gudbes@protonmail.com>, 2020
# Greg Greg <grena@grenabox.fr>, 2020
# Luclu7 <theluc7andcompagnie@gmail.com>, 2020
# Julien Veyssier <eneiluj@gmx.fr>, 2020
#
msgid ""
msgstr ""
"Last-Translator: Julien Veyssier <eneiluj@gmx.fr>, 2020\n"
"Language-Team: French (https://www.transifex.com/nextcloud/teams/64236/fr/)\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Language: fr\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"

#: src/components/MultiselectTags/MultiselectTags.vue:170
#: lib/toast.ts:187
msgid "Undo"
msgstr "Annuler"
Comment on lines +1 to +20

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dummy file, will get overrided, it's fine

7 changes: 7 additions & 0 deletions l10n/messages.pot
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"

#: lib/toast.ts:187
msgid "Undo"
msgstr ""
2 changes: 1 addition & 1 deletion lib/filepicker.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/// <reference types="@nextcloud/typings" />

declare var OC: Nextcloud.v16.OC | Nextcloud.v17.OC | Nextcloud.v18.OC | Nextcloud.v19.OC;
declare const OC: Nextcloud.v16.OC | Nextcloud.v17.OC | Nextcloud.v18.OC | Nextcloud.v19.OC;

export enum FilePickerType {
Choose = 1,
Expand Down
2 changes: 1 addition & 1 deletion lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { FilePicker, FilePickerBuilder, getFilePickerBuilder } from './filepicker'
export { showMessage, showSuccess, showWarning, showInfo, showError } from './toast'
export { showMessage, showSuccess, showWarning, showInfo, showError, showUndo } from './toast'
12 changes: 12 additions & 0 deletions lib/l10n.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { getGettextBuilder } from '@nextcloud/l10n/dist/gettext'

const gtBuilder = getGettextBuilder()
.detectLocale()

process.env.TRANSLATIONS
.map(data => gtBuilder.addTranslation(data.locale, data.json))

const gt = gtBuilder.build()

export const n = gt.ngettext.bind(gt)
export const t = gt.gettext.bind(gt)
93 changes: 84 additions & 9 deletions lib/toast.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,40 @@
/**
* @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
* @author John Molakvoæ <skjnldsv@protonmail.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import Toastify from 'toastify-js'
import { t } from './l10n.js'

class ToastType {
static readonly ERROR = 'toast-error';
static readonly WARNING = 'toast-warning';
static readonly INFO = 'toast-info';
static readonly SUCCESS = 'toast-success';
static readonly PERMANENT = 'toast-error';
static readonly UNDO = 'toast-undo';
}

export interface ToastOptions {
/**
* Defines the timeout after which the toast is closed. Set to 0 to have a persistent toast.
* Defines the timeout after which the toast is closed. Set to -1 to have a persistent toast.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per #107 and #111 this is not intended.

*/
timeout?: number

Expand Down Expand Up @@ -52,36 +76,43 @@ export interface ToastOptions {
* @param text Message to be shown in the toast, any HTML is removed by default
* @param options
*/
export function showMessage(text: string, options?: ToastOptions): Toast {
export function showMessage(data: string|Node, options?: ToastOptions): Toast {
options = Object.assign({
timeout: 7,
isHTML: false,
type: undefined,
// An undefined selector defaults to the body element
selector: undefined,
onRemove: () => { },
onClick: () => { },
onClick: undefined,
close: true
}, options)
if (!options.isHTML) {

if (typeof data === 'string' && !options.isHTML) {
// fime mae sure that text is extracted
const element = document.createElement('div')
element.innerHTML = text
text = element.innerText
element.innerHTML = data
data = element.innerText
}
let classes = options.type ?? ''

if (typeof options.onClick === 'function') {
classes += ' toast-with-click '
}

const isNode = data instanceof Node

const toast = Toastify({
text: text,
duration: (options.timeout === null || options.timeout === undefined) ? null : options.timeout * 1000,
[!isNode ? 'text' : 'node']: data,
duration: options.timeout ? options.timeout * 1000 : null,
callback: options.onRemove,
onClick: options.onClick,
close: options.close,
gravity: 'top',
selector: options.selector,
position: 'right',
backgroundColor: '',
className: 'toast ' + classes,
className: 'dialogs ' + classes,
Comment thread
skjnldsv marked this conversation as resolved.
})
toast.showToast()
return toast
Expand Down Expand Up @@ -126,3 +157,47 @@ export function showInfo(text: string, options?: ToastOptions): Toast {
export function showSuccess(text: string, options?: ToastOptions): Toast {
return showMessage(text, { ...options, type: ToastType.SUCCESS })
}

/**
* Show a toast message with undo styling
*
* @param text Message to be shown in the toast, any HTML is removed by default
* @param onUndo Function that is called when the undo button is clicked
* @param options
*/
export function showUndo(text: string, onUndo: Function, options?: ToastOptions): Toast {
// onUndo callback is mandatory
if (!(onUndo instanceof Function)) {
throw new Error('Please provide a valid onUndo method')
}

let toast

options = Object.assign(options || {}, {
// force 10 seconds of timeout
timeout: 1000,
// remove close button
close: false
})

// Generate undo layout
const undoContent = document.createElement('span')
const undoButton = document.createElement('button')
undoButton.classList.add('toast-undo-button')
undoButton.innerText = t('Undo')
undoContent.innerText = text
undoContent.appendChild(undoButton)

undoButton.addEventListener('click', function(event) {
event.stopPropagation()
onUndo(event)

// Hide toast
if (toast?.hideToast instanceof Function) {
toast.hideToast()
}
})

toast = showMessage(undoContent, { ...options, type: ToastType.UNDO })
return toast
}
3 changes: 2 additions & 1 deletion lib/toastify.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ declare interface ToastElement {
declare module 'toastify-js' {

interface ToastifyOptions {
text: string,
text?: string,
Comment thread
skjnldsv marked this conversation as resolved.
node?: Node,
duration?: number|null,
destination?: string|undefined,
newWindow?: Boolean,
Expand Down
Loading