Skip to content

Commit

Permalink
enh(ui): Add git adapter UI
Browse files Browse the repository at this point in the history
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
  • Loading branch information
marcelklehr committed May 4, 2024
1 parent b658752 commit da64c3f
Show file tree
Hide file tree
Showing 4 changed files with 255 additions and 4 deletions.
15 changes: 15 additions & 0 deletions _locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@
"DescriptionBookmarksfilegoogle": {
"message": "the file name of the bookmarks file that will reside in your Google Drive (make sure this name is unique in your Drive)"
},
"DescriptionBookmarksfilegit": {
"message": "a path to the bookmarks file relative to your Git repository root (all folders in the path must already exist). e.g. personal_stuff/bookmarks.xbel"
},
"LabelServerfolder": {
"message": "Server target"
},
Expand Down Expand Up @@ -689,5 +692,17 @@
},
"DescriptionSyncscheduled": {
"message": "This profile will be synced soon. We're either waiting for other devices of yours, or other profiles on this device, to finish syncing."
},
"LabelAdaptergit": {
"message": "Git over HTTPS"
},
"DescriptionAdaptergit": {
"message": "The Git option syncs your bookmarks by storing them in a file in the provided Git repository. There is no accompanying web UI for this option, but you can use it with any Git hosting server, like Github, Gitlab, Gitea, etc. It can sync http, ftp, data, file and javascript bookmarks."
},
"LabelGiturl": {
"message": "Repository URL using HTTP"
},
"LabelGitbranch": {
"message": "Git branch"
}
}
175 changes: 175 additions & 0 deletions src/ui/components/OptionsGit.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
<template>
<v-container>
<v-card class="mb-4">
<v-card-text
id="server"
class="text-h5">
<v-icon>mdi-account-box</v-icon>
{{ t('LabelOptionsServerDetails') }}
</v-card-text>
<v-card-text>
<v-text-field
:value="url"
:rules="[validateUrl]"
:label="t('LabelGiturl')"
@input="$emit('update:url', $event)" />
<v-text-field
:value="username"
:label="t('LabelUsername')"
@input="$emit('update:username', $event)" />
<v-text-field
:label="t('LabelPassword')"
:append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
:type="showPassword ? 'text' : 'password'"
@click:append="showPassword = !showPassword"
@input="$emit('update:password', $event)" />
<v-text-field
append-icon="mdi-file-document"
:value="bookmark_file"
:rules="[validateBookmarksFile]"
:label="t('LabelBookmarksfile')"
:hint="t('DescriptionBookmarksfilegit')"
:persistent-hint="true"
@input="$emit('update:bookmark_file', $event)" />
<OptionFileType
:value="bookmark_file_type"
@input="$emit('update:bookmark_file_type', $event)" />
<v-text-field
v-model="branch"
class="mb-2"
:label="t('LabelGitbranch')" />
</v-card-text>
</v-card>

<v-card
v-if="isBrowser"
class="mb-4">
<v-card-title
id="folder"
class="text-h5">
<v-icon>mdi-folder-outline</v-icon>
{{ t('LabelOptionsFolderMapping') }}
</v-card-title>
<v-card-text>
<OptionSyncFolder
:value="localRoot"
@input="$emit('update:localRoot', $event)" />
</v-card-text>
</v-card>

<v-card
v-if="!isBrowser"
class="mb-4">
<v-card-title
id="mobile"
class="text-h5">
<v-icon>mdi-cellphone-settings</v-icon>
{{ t('LabelMobilesettings') }}
</v-card-title>
<v-card-text>
<OptionAllowNetwork
:value="allowNetwork"
@input="$emit('update:allowNetwork', $event)" />
<OptionExportBookmarks />
</v-card-text>
</v-card>

<v-card class="mb-4">
<v-card-title
id="sync"
class="text-h5">
<v-icon>mdi-sync-circle</v-icon>
{{ t('LabelOptionsSyncBehavior') }}
</v-card-title>
<v-card-text>
<v-switch
:input-value="enabled"
:aria-label="t('LabelAutosync')"
:label="t('LabelAutosync')"
dense
class="mt-0 pt-0"
@change="$emit('update:enabled', $event)" />
<OptionSyncInterval
:value="syncInterval"
@input="$emit('update:syncInterval', $event)" />
<OptionSyncStrategy
:value="strategy"
@input="$emit('update:strategy', $event)" />
<OptionNestedSync
v-if="isBrowser"
:value="nestedSync"
@input="$emit('update:nestedSync', $event)" />
</v-card-text>
</v-card>

<v-card class="mb-4">
<v-card-title
id="danger"
class="text-h5">
<v-icon>mdi-alert-circle</v-icon>
{{ t('LabelOptionsDangerous') }}
</v-card-title>
<v-card-text>
<OptionDownloadLogs />
<OptionClientCert
v-if="isBrowser"
:value="includeCredentials"
@input="$emit('update:includeCredentials', $event)" />
<OptionAllowRedirects
v-if="isBrowser"
:value="allowRedirects"
@input="$emit('update:allowRedirects', $event)" />
<OptionResetCache @click="$emit('reset')" />
<OptionFailsafe
:value="failsafe"
@input="$emit('update:failsafe', $event)" />
<OptionDeleteAccount @click="$emit('delete')" />
</v-card-text>
</v-card>
</v-container>
</template>

<script>
import OptionSyncInterval from './OptionSyncInterval'
import OptionResetCache from './OptionResetCache'
import OptionSyncStrategy from './OptionSyncStrategy'
import OptionDeleteAccount from './OptionDeleteAccount'
import OptionSyncFolder from './OptionSyncFolder'
import OptionNestedSync from './OptionNestedSync'
import OptionFailsafe from './OptionFailsafe'
import OptionClientCert from './OptionClientCert'
import OptionAllowRedirects from './OptionAllowRedirects'
import OptionDownloadLogs from './OptionDownloadLogs'
import OptionAllowNetwork from './native/OptionAllowNetwork'
import OptionFileType from './OptionFileType'
import OptionExportBookmarks from './OptionExportBookmarks.vue'
export default {
name: 'OptionsGit',
components: { OptionExportBookmarks, OptionAllowNetwork, OptionDownloadLogs, OptionAllowRedirects, OptionClientCert, OptionFailsafe, OptionSyncFolder, OptionDeleteAccount, OptionSyncStrategy, OptionResetCache, OptionSyncInterval, OptionNestedSync, OptionFileType },
props: ['url', 'username', 'password', 'branch', 'includeCredentials', 'serverRoot', 'localRoot', 'allowNetwork', 'syncInterval', 'strategy', 'bookmark_file', 'nestedSync', 'failsafe', 'allowRedirects', 'bookmark_file_type', 'enabled'],
data() {
return {
panels: [0, 1],
showPassword: false,
showPassphrase: false,
}
},
methods: {
validateUrl(str) {
try {
const u = new URL(str)
return Boolean(u) && u.protocol.startsWith('http')
} catch (e) {
return false
}
},
validateBookmarksFile(path) {
return path[0] !== '/' && path[path.length - 1] !== '/'
},
}
}
</script>

<style scoped>
</style>
9 changes: 7 additions & 2 deletions src/ui/views/AccountOptions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@
v-bind.sync="data"
@reset="onReset"
@delete="onDelete" />
<OptionsGit
v-if="data.type === 'git'"
v-bind.sync="data"
@reset="onReset"
@delete="onDelete" />
<OptionsFake
v-if="data.type === 'fake'"
v-bind.sync="data"
Expand Down Expand Up @@ -191,11 +196,11 @@ import OptionsNextcloudFolders from '../components/OptionsNextcloudBookmarks'
import OptionsWebdav from '../components/OptionsWebdav'
import OptionsFake from '../components/OptionsFake'
import OptionsGoogleDrive from '../components/OptionsGoogleDrive'
// import OptionsGoogleDrive from '../components/OptionsGoogleDrive'
import OptionsGit from '../components/OptionsGit.vue'
export default {
name: 'AccountOptions',
components: { OptionsGoogleDrive, OptionsFake, OptionsWebdav, OptionsNextcloudFolders },
components: { OptionsGit, OptionsGoogleDrive, OptionsFake, OptionsWebdav, OptionsNextcloudFolders },
data() {
return {
folderName: '',
Expand Down
60 changes: 58 additions & 2 deletions src/ui/views/NewAccount.vue
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,35 @@
</div>
</template>

<template v-else-if="adapter === 'git'">
<div class="headline">
{{ t('LabelServersetup') }}
</div>
<v-text-field
v-model="server"
:rules="[validateUrl]"
:label="t('LabelGiturl')" />
<v-text-field
v-model="username"
:label="t('LabelUsername')" />
<v-text-field
v-model="password"
:label="t('LabelPassword')"
:append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
:type="showPassword ? 'text' : 'password'"
@click:append="showPassword = !showPassword" />
<div class="d-flex flex-row justify-space-between">
<v-btn @click="currentStep--">
{{ t('LabelBack') }}
</v-btn>
<v-btn
class="primary"
@click="currentStep++">
{{ t('LabelContinue') }}
</v-btn>
</div>
</template>

<template v-else-if="adapter === 'google-drive'">
<div class="headline">
{{ t('LabelGoogledrivesetup') }}
Expand Down Expand Up @@ -203,6 +232,26 @@
v-model="bookmark_file_type" />
</template>

<template v-if="adapter === 'git'">
<div class="text-h6">
{{ t('LabelBookmarksfile') }}
</div>
<v-text-field
v-model="bookmark_file"
class="mb-2"
append-icon="mdi-file-document"
:rules="[validateBookmarksFile]"
:label="t('LabelBookmarksfile')"
:hint="t('DescriptionBookmarksfilegit')"
:persistent-hint="true" />
<OptionFileType
v-model="bookmark_file_type" />
<v-text-field
v-model="branch"
class="mb-2"
:label="t('LabelGitbranch')" />
</template>

<template v-if="adapter === 'google-drive'">
<div class="text-h6">
{{ t('LabelBookmarksfile') }}
Expand Down Expand Up @@ -302,6 +351,7 @@ export default {
serverTestSuccessful: false,
loginFlowError: '',
server: 'https://',
branch: 'main',
username: '',
password: '',
passphrase: '',
Expand All @@ -328,6 +378,11 @@ export default {
label: this.t('LabelAdapterwebdav'),
description: this.t('DescriptionAdapterwebdav')
},
{
type: 'git',
label: this.t('LabelAdaptergit'),
description: this.t('DescriptionAdaptergit')
},
{
type: 'google-drive',
label: this.t('LabelAdaptergoogledrive'),
Expand Down Expand Up @@ -356,8 +411,9 @@ export default {
password: this.password,
enabled: this.enabled,
...(this.adapter === 'nextcloud-bookmarks' && {serverRoot: this.serverRoot}),
...((this.adapter === 'webdav' || this.adapter === 'google-drive') && {bookmark_file: this.bookmark_file}),
...((this.adapter === 'webdav' || this.adapter === 'google-drive') && {bookmark_file_type: this.bookmark_file_type}),
...(this.adapter === 'git' && {branch: this.branch}),
...((this.adapter === 'webdav' || this.adapter === 'google-drive' || this.adapter === 'git') && {bookmark_file: this.bookmark_file}),
...((this.adapter === 'webdav' || this.adapter === 'google-drive' || this.adapter === 'git') && {bookmark_file_type: this.bookmark_file_type}),
...(this.adapter === 'google-drive' && {refreshToken: this.refreshToken}),
...(this.passphrase && {passphrase: this.passphrase}),
...(this.adapter === 'google-drive' && this.passphrase && {password: this.passphrase}),
Expand Down

0 comments on commit da64c3f

Please sign in to comment.