Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wiki-js
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
wiki-js
Commits
1def5289
Commit
1def5289
authored
Apr 06, 2020
by
NGPixel
Committed by
Nicolas Giard
May 21, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: admin comments page
parent
bb21f6ed
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
515 additions
and
39 deletions
+515
-39
admin.vue
client/components/admin.vue
+3
-2
admin-comments.vue
client/components/admin/admin-comments.vue
+205
-0
icon-chat-bubble.svg
client/static/svg/icon-chat-bubble.svg
+2
-0
kernel.js
server/core/kernel.js
+1
-0
2.3.14.js
server/db/migrations-sqlite/2.3.14.js
+10
-0
2.3.14.js
server/db/migrations/2.3.14.js
+16
-0
comment.js
server/graph/resolvers/comment.js
+55
-37
comment.graphql
server/graph/schemas/comment.graphql
+52
-0
commentProviders.js
server/models/commentProviders.js
+100
-0
code.yml
server/modules/comments/commento/code.yml
+4
-0
definition.yml
server/modules/comments/commento/definition.yml
+17
-0
definition.yml
server/modules/comments/default/definition.yml
+19
-0
code.yml
server/modules/comments/disqus/code.yml
+15
-0
definition.yml
server/modules/comments/disqus/definition.yml
+16
-0
No files found.
client/components/admin.vue
View file @
1def5289
...
@@ -62,8 +62,8 @@
...
@@ -62,8 +62,8 @@
v-list-item(to='/auth', color='primary')
v-list-item(to='/auth', color='primary')
v-list-item-avatar(size='24', tile): v-icon mdi-lock-outline
v-list-item-avatar(size='24', tile): v-icon mdi-lock-outline
v-list-item-title
{{
$t
(
'admin:auth.title'
)
}}
v-list-item-title
{{
$t
(
'admin:auth.title'
)
}}
v-list-item(to='/comments'
, disabled
)
v-list-item(to='/comments')
v-list-item-avatar(size='24', tile): v-icon
(color='grey lighten-2')
mdi-comment-text-outline
v-list-item-avatar(size='24', tile): v-icon mdi-comment-text-outline
v-list-item-title
{{
$t
(
'admin:comments.title'
)
}}
v-list-item-title
{{
$t
(
'admin:comments.title'
)
}}
v-list-item(to='/editor', disabled)
v-list-item(to='/editor', disabled)
v-list-item-avatar(size='24', tile): v-icon(color='grey lighten-2') mdi-playlist-edit
v-list-item-avatar(size='24', tile): v-icon(color='grey lighten-2') mdi-playlist-edit
...
@@ -171,6 +171,7 @@ const router = new VueRouter({
...
@@ -171,6 +171,7 @@ const router = new VueRouter({
{
path
:
'/users/:id(
\\
d+)'
,
component
:
()
=>
import
(
/* webpackChunkName: "admin" */
'./admin/admin-users-edit.vue'
)
},
{
path
:
'/users/:id(
\\
d+)'
,
component
:
()
=>
import
(
/* webpackChunkName: "admin" */
'./admin/admin-users-edit.vue'
)
},
{
path
:
'/analytics'
,
component
:
()
=>
import
(
/* webpackChunkName: "admin" */
'./admin/admin-analytics.vue'
)
},
{
path
:
'/analytics'
,
component
:
()
=>
import
(
/* webpackChunkName: "admin" */
'./admin/admin-analytics.vue'
)
},
{
path
:
'/auth'
,
component
:
()
=>
import
(
/* webpackChunkName: "admin" */
'./admin/admin-auth.vue'
)
},
{
path
:
'/auth'
,
component
:
()
=>
import
(
/* webpackChunkName: "admin" */
'./admin/admin-auth.vue'
)
},
{
path
:
'/comments'
,
component
:
()
=>
import
(
/* webpackChunkName: "admin" */
'./admin/admin-comments.vue'
)
},
{
path
:
'/rendering'
,
component
:
()
=>
import
(
/* webpackChunkName: "admin" */
'./admin/admin-rendering.vue'
)
},
{
path
:
'/rendering'
,
component
:
()
=>
import
(
/* webpackChunkName: "admin" */
'./admin/admin-rendering.vue'
)
},
{
path
:
'/editor'
,
component
:
()
=>
import
(
/* webpackChunkName: "admin" */
'./admin/admin-editor.vue'
)
},
{
path
:
'/editor'
,
component
:
()
=>
import
(
/* webpackChunkName: "admin" */
'./admin/admin-editor.vue'
)
},
{
path
:
'/extensions'
,
component
:
()
=>
import
(
/* webpackChunkName: "admin" */
'./admin/admin-extensions.vue'
)
},
{
path
:
'/extensions'
,
component
:
()
=>
import
(
/* webpackChunkName: "admin" */
'./admin/admin-extensions.vue'
)
},
...
...
client/components/admin/admin-comments.vue
0 → 100644
View file @
1def5289
<
template
lang=
'pug'
>
v-container(fluid, grid-list-lg)
v-layout(row, wrap)
v-flex(xs12)
.admin-header
img.animated.fadeInUp(src='/svg/icon-chat-bubble.svg', alt='Comments', style='width: 80px;')
.admin-header-title
.headline.primary--text.animated.fadeInLeft
{{
$t
(
'admin:comments.title'
)
}}
.subtitle-1.grey--text.animated.fadeInLeft.wait-p2s
{{
$t
(
'admin:comments.subtitle'
)
}}
v-spacer
v-btn.mx-1.animated.fadeInDown.wait-p2s(outlined, color='grey', @click='refresh', large)
v-icon mdi-refresh
v-btn.ml-1.animated.fadeInDown(color='success', @click='save', depressed, large)
v-icon(left) mdi-check
span
{{
$t
(
'common:actions.apply'
)
}}
v-flex(lg3, xs12)
v-card.animated.fadeInUp
v-toolbar(flat, color='primary', dark, dense)
.subtitle-1
{{
$t
(
'admin:comments.providers'
)
}}
v-list.py-0(two-line, dense)
template(v-for='(provider, idx) in providers')
v-list-item(:key='provider.key', @click='selectedProvider = provider.key', :disabled='!provider.isAvailable')
v-list-item-avatar(size='24')
v-icon(color='grey', v-if='!provider.isAvailable') mdi-minus-box-outline
v-icon(color='primary', v-else-if='provider.key === selectedProvider') mdi-checkbox-marked-circle-outline
v-icon(color='grey', v-else) mdi-checkbox-blank-circle-outline
v-list-item-content
v-list-item-title.body-2(:class='!provider.isAvailable ? `grey--text` : (selectedProvider === provider.key ? `primary--text` : ``)')
{{
provider
.
title
}}
v-list-item-subtitle: .caption(:class='!provider.isAvailable ? `grey--text text--lighten-1` : (selectedProvider === provider.key ? `blue--text ` : ``)')
{{
provider
.
description
}}
v-list-item-avatar(v-if='selectedProvider === provider.key', size='24')
v-icon.animated.fadeInLeft(color='primary', large) mdi-chevron-right
v-divider(v-if='idx < providers.length - 1')
v-flex(lg9, xs12)
v-card.animated.fadeInUp.wait-p2s
v-toolbar(color='primary', dense, flat, dark)
.subtitle-1
{{
provider
.
title
}}
v-card-text
.providerlogo
img(:src='provider.logo', :alt='provider.title')
.caption.pt-3
{{
provider
.
description
}}
.caption.pb-3: a(:href='provider.website')
{{
provider
.
website
}}
v-divider.mt-3
.overline.my-5
{{
$t
(
'admin:comments.providerConfig'
)
}}
.body-2.ml-3(v-if='!provider.config || provider.config.length < 1'): em
{{
$t
(
'admin:comments.providerNoConfig'
)
}}
template(v-else, v-for='cfg in provider.config')
v-select(
v-if='cfg.value.type === "string" && cfg.value.enum'
outlined
:items='cfg.value.enum'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
prepend-icon='mdi-cog-box'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
:class='cfg.value.hint ? "mb-2" : ""'
)
v-switch.mb-3(
v-else-if='cfg.value.type === "boolean"'
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
color='primary'
prepend-icon='mdi-cog-box'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
inset
)
v-textarea(
v-else-if='cfg.value.type === "string" && cfg.value.multiline'
outlined
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
prepend-icon='mdi-cog-box'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
:class='cfg.value.hint ? "mb-2" : ""'
)
v-text-field(
v-else
outlined
:key='cfg.key'
:label='cfg.value.title'
v-model='cfg.value.value'
prepend-icon='mdi-cog-box'
:hint='cfg.value.hint ? cfg.value.hint : ""'
persistent-hint
:class='cfg.value.hint ? "mb-2" : ""'
)
</
template
>
<
script
>
import
_
from
'lodash'
import
gql
from
'graphql-tag'
export
default
{
data
()
{
return
{
providers
:
[],
selectedProvider
:
''
,
provider
:
{}
}
},
watch
:
{
selectedProvider
(
newValue
,
oldValue
)
{
this
.
provider
=
_
.
find
(
this
.
providers
,
[
'key'
,
newValue
])
||
{}
},
providers
(
newValue
,
oldValue
)
{
this
.
selectedProvider
=
_
.
get
(
_
.
find
(
this
.
providers
,
'isEnabled'
),
'key'
,
'db'
)
}
},
methods
:
{
async
refresh
()
{
await
this
.
$apollo
.
queries
.
providers
.
refetch
()
this
.
$store
.
commit
(
'showNotification'
,
{
message
:
this
.
$t
(
'admin:comments.listRefreshSuccess'
),
style
:
'success'
,
icon
:
'cached'
})
},
async
save
()
{
this
.
$store
.
commit
(
`loadingStart`
,
'admin-comments-saveproviders'
)
try
{
const
resp
=
await
this
.
$apollo
.
mutate
({
mutation
:
gql
``
,
variables
:
{
providers
:
this
.
providers
.
map
(
tgt
=>
({
isEnabled
:
tgt
.
key
===
this
.
selectedProvider
,
key
:
tgt
.
key
,
config
:
tgt
.
config
.
map
(
cfg
=>
({...
cfg
,
value
:
JSON
.
stringify
({
v
:
cfg
.
value
.
value
})}))
}))
}
})
if
(
_
.
get
(
resp
,
'data.comments.updateEngines.responseResult.succeeded'
,
false
))
{
this
.
$store
.
commit
(
'showNotification'
,
{
message
:
this
.
$t
(
'admin:comments.configSaveSuccess'
),
style
:
'success'
,
icon
:
'check'
})
}
else
{
throw
new
Error
(
_
.
get
(
resp
,
'data.comments.updateEngines.responseResult.message'
,
this
.
$t
(
'common:error.unexpected'
)))
}
}
catch
(
err
)
{
this
.
$store
.
commit
(
'pushGraphError'
,
err
)
}
this
.
$store
.
commit
(
`loadingStop`
,
'admin-comments-saveengines'
)
}
},
apollo
:
{
providers
:
{
query
:
gql
`
query {
comments {
providers {
isEnabled
key
title
description
logo
website
isAvailable
config {
key
value
}
}
}
}
`
,
fetchPolicy
:
'network-only'
,
update
:
(
data
)
=>
_
.
cloneDeep
(
data
.
comments
.
providers
).
map
(
str
=>
({
...
str
,
config
:
_
.
sortBy
(
str
.
config
.
map
(
cfg
=>
({
...
cfg
,
value
:
JSON
.
parse
(
cfg
.
value
)
})),
[
t
=>
t
.
value
.
order
])
})),
watchLoading
(
isLoading
)
{
this
.
$store
.
commit
(
`loading
${
isLoading
?
'Start'
:
'Stop'
}
`
,
'admin-comments-refresh'
)
}
}
}
}
</
script
>
<
style
lang=
'scss'
scoped
>
.providerlogo
{
width
:
250px
;
height
:
85px
;
float
:right
;
display
:
flex
;
justify-content
:
flex-end
;
align-items
:
center
;
img
{
max-width
:
100%
;
max-height
:
50px
;
}
}
</
style
>
client/static/svg/icon-chat-bubble.svg
0 → 100644
View file @
1def5289
<svg
xmlns=
"http://www.w3.org/2000/svg"
viewBox=
"0 0 64 64"
width=
"96px"
height=
"96px"
><linearGradient
id=
"r6aF76sThYJjByxe12PMJa"
x1=
"26.5"
x2=
"26.5"
y1=
"16.5"
y2=
"26.237"
gradientUnits=
"userSpaceOnUse"
><stop
offset=
"0"
stop-color=
"#6dc7ff"
/><stop
offset=
"1"
stop-color=
"#e6abff"
/></linearGradient><path
fill=
"url(#r6aF76sThYJjByxe12PMJa)"
d=
"M32.832,25H20.168C19.523,25,19,24.477,19,23.832v-5.665C19,17.523,19.523,17,20.168,17 h12.665C33.477,17,34,17.523,34,18.168v5.665C34,24.477,33.477,25,32.832,25z"
/><linearGradient
id=
"r6aF76sThYJjByxe12PMJb"
x1=
"32"
x2=
"32"
y1=
"9.553"
y2=
"54.562"
gradientUnits=
"userSpaceOnUse"
><stop
offset=
"0"
stop-color=
"#1a6dff"
/><stop
offset=
"1"
stop-color=
"#c822ff"
/></linearGradient><path
fill=
"url(#r6aF76sThYJjByxe12PMJb)"
d=
"M49,9H15c-2.758,0-5,2.242-5,4.996v28C10,44.754,12.242,47,15,47h15c0.551,0,1,0.445,1,0.996 v4.102c0,1.133,0.656,2.137,1.719,2.617c0.422,0.191,0.863,0.289,1.301,0.289c0.719,0,1.426-0.258,1.996-0.754l8.074-7.008 C44.273,47.086,44.508,47,44.746,47H49c2.758,0,5-2.246,5-5.004v-28C54,11.242,51.758,9,49,9z M52,41.996 C52,43.652,50.652,45,49,45h-4.254c-0.723,0-1.422,0.262-1.969,0.734l-8.074,7.008c-0.383,0.328-0.848,0.293-1.156,0.152 C33.383,52.82,33,52.594,33,52.098v-4.102C33,46.344,31.652,45,30,45H15c-1.652,0-3-1.348-3-3.004v-28C12,12.344,13.348,11,15,11 h34c1.652,0,3,1.344,3,2.996V41.996z"
/><linearGradient
id=
"r6aF76sThYJjByxe12PMJc"
x1=
"32"
x2=
"32"
y1=
"9.553"
y2=
"54.562"
gradientUnits=
"userSpaceOnUse"
><stop
offset=
"0"
stop-color=
"#1a6dff"
/><stop
offset=
"1"
stop-color=
"#c822ff"
/></linearGradient><rect
width=
"26"
height=
"2"
x=
"19"
y=
"29"
fill=
"url(#r6aF76sThYJjByxe12PMJc)"
/><linearGradient
id=
"r6aF76sThYJjByxe12PMJd"
x1=
"28.5"
x2=
"28.5"
y1=
"9.553"
y2=
"54.562"
gradientUnits=
"userSpaceOnUse"
><stop
offset=
"0"
stop-color=
"#1a6dff"
/><stop
offset=
"1"
stop-color=
"#c822ff"
/></linearGradient><rect
width=
"19"
height=
"2"
x=
"19"
y=
"33"
fill=
"url(#r6aF76sThYJjByxe12PMJd)"
/><linearGradient
id=
"r6aF76sThYJjByxe12PMJe"
x1=
"32"
x2=
"32"
y1=
"9.553"
y2=
"54.562"
gradientUnits=
"userSpaceOnUse"
><stop
offset=
"0"
stop-color=
"#1a6dff"
/><stop
offset=
"1"
stop-color=
"#c822ff"
/></linearGradient><rect
width=
"26"
height=
"2"
x=
"19"
y=
"37"
fill=
"url(#r6aF76sThYJjByxe12PMJe)"
/></svg>
\ No newline at end of file
server/core/kernel.js
View file @
1def5289
...
@@ -69,6 +69,7 @@ module.exports = {
...
@@ -69,6 +69,7 @@ module.exports = {
async
postBootMaster
()
{
async
postBootMaster
()
{
await
WIKI
.
models
.
analytics
.
refreshProvidersFromDisk
()
await
WIKI
.
models
.
analytics
.
refreshProvidersFromDisk
()
await
WIKI
.
models
.
authentication
.
refreshStrategiesFromDisk
()
await
WIKI
.
models
.
authentication
.
refreshStrategiesFromDisk
()
await
WIKI
.
models
.
commentProviders
.
refreshProvidersFromDisk
()
await
WIKI
.
models
.
editors
.
refreshEditorsFromDisk
()
await
WIKI
.
models
.
editors
.
refreshEditorsFromDisk
()
await
WIKI
.
models
.
loggers
.
refreshLoggersFromDisk
()
await
WIKI
.
models
.
loggers
.
refreshLoggersFromDisk
()
await
WIKI
.
models
.
renderers
.
refreshRenderersFromDisk
()
await
WIKI
.
models
.
renderers
.
refreshRenderersFromDisk
()
...
...
server/db/migrations-sqlite/2.3.14.js
0 → 100644
View file @
1def5289
exports
.
up
=
knex
=>
{
return
knex
.
schema
.
createTable
(
'commentProviders'
,
table
=>
{
table
.
string
(
'key'
).
notNullable
().
primary
()
table
.
boolean
(
'isEnabled'
).
notNullable
().
defaultTo
(
false
)
table
.
json
(
'config'
).
notNullable
()
})
}
exports
.
down
=
knex
=>
{
}
server/db/migrations/2.3.14.js
0 → 100644
View file @
1def5289
/* global WIKI */
exports
.
up
=
knex
=>
{
const
dbCompat
=
{
charset
:
(
WIKI
.
config
.
db
.
type
===
`mysql`
||
WIKI
.
config
.
db
.
type
===
`mariadb`
)
}
return
knex
.
schema
.
createTable
(
'commentProviders'
,
table
=>
{
if
(
dbCompat
.
charset
)
{
table
.
charset
(
'utf8mb4'
)
}
table
.
string
(
'key'
).
notNullable
().
primary
()
table
.
boolean
(
'isEnabled'
).
notNullable
().
defaultTo
(
false
)
table
.
json
(
'config'
).
notNullable
()
})
}
exports
.
down
=
knex
=>
{
}
server/graph/resolvers/comment.js
View file @
1def5289
const
_
=
require
(
'lodash'
)
const
graphHelper
=
require
(
'../../helpers/graph'
)
/* global WIKI */
module
.
exports
=
{
module
.
exports
=
{
// Query: {
Query
:
{
// comments(obj, args, context, info) {
async
comments
()
{
return
{}
}
// return WIKI.models.Comment.findAll({ where: args })
},
// }
Mutation
:
{
// },
async
comments
()
{
return
{}
}
// Mutation: {
},
// createComment(obj, args) {
CommentQuery
:
{
// return WIKI.models.Comment.create({
async
providers
(
obj
,
args
,
context
,
info
)
{
// content: args.content,
const
providers
=
await
WIKI
.
models
.
commentProviders
.
getProviders
()
// author: args.userId,
return
providers
.
map
(
provider
=>
{
// document: args.documentId
const
providerInfo
=
_
.
find
(
WIKI
.
data
.
commentProviders
,
[
'key'
,
provider
.
key
])
||
{}
// })
return
{
// },
...
providerInfo
,
// deleteComment(obj, args) {
...
provider
,
// return WIKI.models.Comment.destroy({
config
:
_
.
sortBy
(
_
.
transform
(
provider
.
config
,
(
res
,
value
,
key
)
=>
{
// where: {
const
configData
=
_
.
get
(
providerInfo
.
props
,
key
,
false
)
// id: args.id
if
(
configData
)
{
// },
res
.
push
({
// limit: 1
key
,
// })
value
:
JSON
.
stringify
({
// },
...
configData
,
// modifyComment(obj, args) {
value
// return WIKI.models.Comment.update({
})
// content: args.content
})
// }, {
}
// where: { id: args.id }
},
[]),
'key'
)
// })
}
// }
})
// },
}
// Comment: {
},
// author(cm) {
CommentMutation
:
{
// return cm.getAuthor()
async
updateProviders
(
obj
,
args
,
context
)
{
// },
try
{
// document(cm) {
for
(
let
provider
of
args
.
providers
)
{
// return cm.getDocument()
await
WIKI
.
models
.
providers
.
query
().
patch
({
// }
isEnabled
:
provider
.
isEnabled
,
// }
config
:
_
.
reduce
(
provider
.
config
,
(
result
,
value
,
key
)
=>
{
_
.
set
(
result
,
`
${
value
.
key
}
`
,
_
.
get
(
JSON
.
parse
(
value
.
value
),
'v'
,
null
))
return
result
},
{})
}).
where
(
'key'
,
provider
.
key
)
}
return
{
responseResult
:
graphHelper
.
generateSuccess
(
'Comment Providers updated successfully'
)
}
}
catch
(
err
)
{
return
graphHelper
.
generateError
(
err
)
}
}
}
}
}
server/graph/schemas/comment.graphql
0 → 100644
View file @
1def5289
# ===============================================
# COMMENT
# ===============================================
extend
type
Query
{
comments
:
CommentQuery
}
extend
type
Mutation
{
comments
:
CommentMutation
}
# -----------------------------------------------
# QUERIES
# -----------------------------------------------
type
CommentQuery
{
providers
:
[
CommentProvider
]
@
auth
(
requires
:
[
"
manage
:
system
"
])
}
# -----------------------------------------------
# MUTATIONS
# -----------------------------------------------
type
CommentMutation
{
updateProviders
(
providers
:
[
CommentProviderInput
]
):
DefaultResponse
@
auth
(
requires
:
[
"
manage
:
system
"
])
rebuildIndex
:
DefaultResponse
@
auth
(
requires
:
[
"
manage
:
system
"
])
}
# -----------------------------------------------
# TYPES
# -----------------------------------------------
type
CommentProvider
{
isEnabled
:
Boolean
!
key
:
String
!
title
:
String
!
description
:
String
logo
:
String
website
:
String
isAvailable
:
Boolean
config
:
[
KeyValuePair
]
}
input
CommentProviderInput
{
isEnabled
:
Boolean
!
key
:
String
!
config
:
[
KeyValuePairInput
]
}
server/models/commentProviders.js
0 → 100644
View file @
1def5289
const
Model
=
require
(
'objection'
).
Model
const
fs
=
require
(
'fs-extra'
)
const
path
=
require
(
'path'
)
const
_
=
require
(
'lodash'
)
const
yaml
=
require
(
'js-yaml'
)
const
commonHelper
=
require
(
'../helpers/common'
)
/* global WIKI */
/**
* CommentProvider model
*/
module
.
exports
=
class
CommentProvider
extends
Model
{
static
get
tableName
()
{
return
'commentProviders'
}
static
get
idColumn
()
{
return
'key'
}
static
get
jsonSchema
()
{
return
{
type
:
'object'
,
required
:
[
'key'
,
'isEnabled'
],
properties
:
{
key
:
{
type
:
'string'
},
isEnabled
:
{
type
:
'boolean'
}
}
}
}
static
get
jsonAttributes
()
{
return
[
'config'
]
}
static
async
getProvider
(
key
)
{
return
WIKI
.
models
.
commentProviders
.
query
().
findOne
({
key
})
}
static
async
getProviders
(
isEnabled
)
{
const
providers
=
await
WIKI
.
models
.
commentProviders
.
query
().
where
(
_
.
isBoolean
(
isEnabled
)
?
{
isEnabled
}
:
{})
return
_
.
sortBy
(
providers
,
[
'key'
])
}
static
async
refreshProvidersFromDisk
()
{
let
trx
try
{
const
dbProviders
=
await
WIKI
.
models
.
commentProviders
.
query
()
// -> Fetch definitions from disk
const
authDirs
=
await
fs
.
readdir
(
path
.
join
(
WIKI
.
SERVERPATH
,
'modules/comments'
))
let
diskProviders
=
[]
for
(
let
dir
of
authDirs
)
{
const
def
=
await
fs
.
readFile
(
path
.
join
(
WIKI
.
SERVERPATH
,
'modules/comments'
,
dir
,
'definition.yml'
),
'utf8'
)
diskProviders
.
push
(
yaml
.
safeLoad
(
def
))
}
WIKI
.
data
.
commentProviders
=
diskProviders
.
map
(
engine
=>
({
...
engine
,
props
:
commonHelper
.
parseModuleProps
(
engine
.
props
)
}))
let
newProviders
=
[]
for
(
let
engine
of
WIKI
.
data
.
commentProviders
)
{
if
(
!
_
.
some
(
dbProviders
,
[
'key'
,
engine
.
key
]))
{
newProviders
.
push
({
key
:
engine
.
key
,
isEnabled
:
engine
.
key
===
'default'
,
config
:
_
.
transform
(
engine
.
props
,
(
result
,
value
,
key
)
=>
{
_
.
set
(
result
,
key
,
value
.
default
)
return
result
},
{})
})
}
else
{
const
engineConfig
=
_
.
get
(
_
.
find
(
dbProviders
,
[
'key'
,
engine
.
key
]),
'config'
,
{})
await
WIKI
.
models
.
commentProviders
.
query
().
patch
({
config
:
_
.
transform
(
engine
.
props
,
(
result
,
value
,
key
)
=>
{
if
(
!
_
.
has
(
result
,
key
))
{
_
.
set
(
result
,
key
,
value
.
default
)
}
return
result
},
engineConfig
)
}).
where
(
'key'
,
engine
.
key
)
}
}
if
(
newProviders
.
length
>
0
)
{
trx
=
await
WIKI
.
models
.
Objection
.
transaction
.
start
(
WIKI
.
models
.
knex
)
for
(
let
engine
of
newProviders
)
{
await
WIKI
.
models
.
commentProviders
.
query
(
trx
).
insert
(
engine
)
}
await
trx
.
commit
()
WIKI
.
logger
.
info
(
`Loaded
${
newProviders
.
length
}
new comment providers: [ OK ]`
)
}
else
{
WIKI
.
logger
.
info
(
`No new comment providers found: [ SKIPPED ]`
)
}
}
catch
(
err
)
{
WIKI
.
logger
.
error
(
`Failed to scan or load new comment providers: [ FAILED ]`
)
WIKI
.
logger
.
error
(
err
)
if
(
trx
)
{
trx
.
rollback
()
}
}
}
}
server/modules/comments/commento/code.yml
0 → 100644
View file @
1def5289
main
:
|
<div id="commento"></div>
bodyEnd
:
|
<script defer src="{{instanceUrl}}/js/commento.js"></script>
server/modules/comments/commento/definition.yml
0 → 100644
View file @
1def5289
key
:
commento
title
:
Commento
description
:
A fast, privacy-focused commenting platform.
author
:
requarks.io
logo
:
https://static.requarks.io/logo/commento.svg
website
:
https://commento.io/
displayMode
:
footer
codeTemplate
:
true
isAvailable
:
true
props
:
instanceUrl
:
type
:
String
title
:
Instance URL
default
:
'
https://cdn.commento.io'
hint
:
The URL (without a trailing slash) to the Commento instance. Leave the default https://cdn.commento.io if using the cloud-hosted version.
order
:
1
server/modules/comments/default/definition.yml
0 → 100644
View file @
1def5289
key
:
default
title
:
Default
description
:
Built-in advanced comments tool.
author
:
requarks.io
logo
:
https://static.requarks.io/logo/wikijs-butterfly.svg
website
:
https://wiki.js.org
displayMode
:
dynamic
codeTemplate
:
false
isAvailable
:
true
props
:
displayMode
:
type
:
String
title
:
Display mode
default
:
'
page'
enum
:
-
inline
-
page
hint
:
Whether to display the comments under the content (inline) or on a dedicated page (page).
order
:
1
server/modules/comments/disqus/code.yml
0 → 100644
View file @
1def5289
main
:
|
<div id="disqus_thread"></div>
bodyEnd
:
|
<script>
var disqus_config = function () {
this.page.url = {{pageUrl}};
this.page.identifier = {{pageId}};
};
(function() {
var d = document, s = d.createElement('script');
s.src = 'https://{{shortName}}.disqus.com/embed.js';
s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
})();
</script>
server/modules/comments/disqus/definition.yml
0 → 100644
View file @
1def5289
key
:
disqus
title
:
Disqus
description
:
Disqus help publishers power online discussions with comments.
author
:
requarks.io
logo
:
https://static.requarks.io/logo/disqus.svg
website
:
https://disqus.com/
displayMode
:
footer
codeTemplate
:
true
isAvailable
:
true
props
:
accountName
:
type
:
String
title
:
Shortname
default
:
'
'
hint
:
Unique identifier from Disqus to identify your website
order
:
1
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment