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
You need to sign in or sign up before continuing.
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