浏览代码

feat: editor - existing content

Nicolas Giard 6 年之前
父节点
当前提交
30806d3c8d

+ 4 - 4
client/app.js

@@ -110,13 +110,13 @@ Vue.prototype.Velocity = Velocity
 // ====================================
 
 Vue.component('admin', () => import(/* webpackChunkName: "admin" */ './components/admin.vue'))
-Vue.component('editor', () => import(/* webpackChunkName: "editor" */ './components/editor.vue'))
-Vue.component('login', () => import(/* webpackMode: "eager" */ './components/login.vue'))
+Vue.component('editor', () => import(/* webpackPrefetch: -100, webpackChunkName: "editor" */ './components/editor.vue'))
+Vue.component('login', () => import(/* webpackPrefetch: true, webpackChunkName: "login" */ './components/login.vue'))
 Vue.component('nav-footer', () => import(/* webpackMode: "eager" */ './components/common/nav-footer.vue'))
-Vue.component('nav-header', () => import(/* webpackMode: "eager" */ './components/common/nav-header.vue'))
+Vue.component('nav-header', () => import(/* webpackMode: "lazy" */ './components/common/nav-header.vue'))
 Vue.component('profile', () => import(/* webpackChunkName: "profile" */ './components/profile.vue'))
 Vue.component('setup', () => import(/* webpackChunkName: "setup" */ './components/setup.vue'))
-Vue.component('v-card-chin', () => import(/* webpackMode: "eager" */ './components/common/v-card-chin.vue'))
+Vue.component('v-card-chin', () => import(/* webpackPrefetch: true, webpackChunkName: "ui-extra" */ './components/common/v-card-chin.vue'))
 Vue.component('page', () => import(/* webpackChunkName: "theme-page" */ './themes/' + process.env.CURRENT_THEME + '/components/app.vue'))
 
 let bootstrap = () => {

+ 46 - 4
client/components/editor.vue

@@ -101,10 +101,48 @@ WIKI.$store.registerModule('editor', editorStore)
 export default {
   components: {
     AtomSpinner,
-    editorCode: () => import(/* webpackChunkName: "editor-code" */ './editor/editor-code.vue'),
-    editorMarkdown: () => import(/* webpackChunkName: "editor-markdown" */ './editor/editor-markdown.vue'),
-    editorWysiwyg: () => import(/* webpackChunkName: "editor-wysiwyg" */ './editor/editor-wysiwyg.vue'),
-    editorModalProperties: () => import(/* webpackChunkName: "editor" */ './editor/editor-modal-properties.vue')
+    editorCode: () => import(/* webpackChunkName: "editor-code", webpackMode: "lazy" */ './editor/editor-code.vue'),
+    editorMarkdown: () => import(/* webpackChunkName: "editor-markdown", webpackMode: "lazy" */ './editor/editor-markdown.vue'),
+    editorWysiwyg: () => import(/* webpackChunkName: "editor-wysiwyg", webpackMode: "lazy" */ './editor/editor-wysiwyg.vue'),
+    editorModalProperties: () => import(/* webpackChunkName: "editor", webpackMode: "eager" */ './editor/editor-modal-properties.vue')
+  },
+  props: {
+    locale: {
+      type: String,
+      default: 'en'
+    },
+    path: {
+      type: String,
+      default: 'home'
+    },
+    title: {
+      type: String,
+      default: 'Untitled Page'
+    },
+    description: {
+      type: String,
+      default: ''
+    },
+    tags: {
+      type: Array,
+      default: () => ([])
+    },
+    isPublished: {
+      type: Boolean,
+      default: false
+    },
+    initEditor: {
+      type: String,
+      default: null
+    },
+    initMode: {
+      type: String,
+      default: 'create'
+    },
+    initContent: {
+      type: String,
+      default: null
+    }
   },
   data() {
     return {
@@ -120,10 +158,14 @@ export default {
     notificationState: sync('notification@isActive')
   },
   mounted() {
+    this.$store.set('editor/mode', this.initMode || 'create')
+    this.$store.set('editor/content', this.initContent ? window.atob(this.initContent) : '# Header\n\nYour content here')
     if (this.mode === 'create') {
       _.delay(() => {
         this.dialogEditorSelector = true
       }, 500)
+    } else {
+      this.selectEditor(this.initEditor || 'markdown')
     }
   },
   methods: {

+ 1 - 1
client/components/editor/editor-markdown.vue

@@ -165,7 +165,7 @@ export default {
   data() {
     return {
       fabInsertMenu: false,
-      code: '# Header 1\n\nSample **Text**\nhttp://wiki.js.org\n:rocket: :) :( :| :P\n\n## Header 2\nSample Text\n\n```javascript\nvar test = require("test");\n\n// some comment\nconst foo = bar(\'param\') + 1.234;\n```\n\n### Header 3\nLorem *ipsum* ~~text~~',
+      code: this.$store.get('editor/content'),
       cmOptions: {
         tabSize: 2,
         mode: 'text/markdown',

+ 4 - 2
dev/webpack/webpack.dev.js

@@ -137,8 +137,7 @@ module.exports = {
       {
         test: /\.svg$/,
         include: [
-          path.join(process.cwd(), 'client/svg'),
-          path.join(process.cwd(), 'node_modules/grapesjs/src/styles/fonts/main-fonts.svg')
+          path.join(process.cwd(), 'client/svg')
         ],
         use: [
           {
@@ -156,6 +155,9 @@ module.exports = {
       },
       {
         test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
+        exclude: [
+          path.join(process.cwd(), 'client')
+        ],
         use: [{
           loader: 'file-loader',
           options: {

+ 15 - 1
dev/webpack/webpack.prod.js

@@ -126,7 +126,8 @@ module.exports = {
       {
         test: /\.svg$/,
         exclude: [
-          path.join(process.cwd(), 'client/svg')
+          path.join(process.cwd(), 'client/svg'),
+          path.join(process.cwd(), 'node_modules/grapesjs')
         ],
         use: [
           {
@@ -157,6 +158,19 @@ module.exports = {
           { loader: 'graphql-tag/loader' }
         ]
       },
+      {
+        test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
+        exclude: [
+          path.join(process.cwd(), 'client')
+        ],
+        use: [{
+          loader: 'file-loader',
+          options: {
+            name: '[name].[ext]',
+            outputPath: 'fonts/'
+          }
+        }]
+      },
       {
         test: /.jsx$/,
         loader: 'babel-loader',

+ 23 - 3
server/controllers/common.js

@@ -7,8 +7,28 @@ const pageHelper = require('../helpers/page')
 /**
  * Create/Edit document
  */
-router.get(['/e', '/e/*'], (req, res, next) => {
-  res.render('editor')
+router.get(['/e', '/e/*'], async (req, res, next) => {
+  const pageArgs = pageHelper.parsePath(req.path)
+  let page = await WIKI.models.pages.getPageFromDb({
+    path: pageArgs.path,
+    locale: pageArgs.locale,
+    userId: req.user.id,
+    isPrivate: false
+  })
+  if (page) {
+    page.mode = 'update'
+    page.isPublished = (page.isPublished === true || page.isPublished === 1) ? 'true' : 'false'
+    page.content = Buffer.from(page.content).toString('base64')
+  } else {
+    page = {
+      path: pageArgs.path,
+      localeCode: pageArgs.locale,
+      editorKey: null,
+      mode: 'create',
+      content: null
+    }
+  }
+  res.render('editor', { page })
 })
 
 /**
@@ -41,7 +61,7 @@ router.get('/*', async (req, res, next) => {
   } else if (pageArgs.path === 'home') {
     res.render('welcome')
   } else {
-    res.render('new')
+    res.render('new', { pagePath: req.path })
   }
 })
 

+ 4 - 1
server/helpers/page.js

@@ -21,8 +21,11 @@ module.exports = {
 
     // Extract Info
     let pathParts = _.filter(_.split(rawPath, '/'), p => !_.isEmpty(p))
+    if (pathParts[0].length === 1) {
+      pathParts.shift()
+    }
     if (pathParts[0].length === 2) {
-      pathObj = pathParts[0]
+      pathObj.locale = pathParts[0]
       pathParts.shift()
     }
     pathObj.path = _.join(pathParts, '/')

+ 3 - 1
server/models/pages.js

@@ -187,7 +187,9 @@ module.exports = class Page extends Model {
     let page = await WIKI.models.pages.getPageFromCache(opts)
     if (!page) {
       page = await WIKI.models.pages.getPageFromDb(opts)
-      await WIKI.models.pages.savePageToCache(page)
+      if (page) {
+        await WIKI.models.pages.savePageToCache(page)
+      }
     }
     return page
   }

+ 11 - 1
server/views/editor.pug

@@ -3,4 +3,14 @@ extends master.pug
 block body
   #root
     v-app
-      editor
+      editor(
+        locale=page.localeCode
+        path=page.path
+        title=page.title
+        description=page.description
+        tags=page.tags
+        :is-published=page.isPublished
+        init-mode=page.mode
+        init-editor=page.editorKey
+        init-content=page.content
+        )

+ 1 - 1
server/views/new.pug

@@ -8,7 +8,7 @@ block body
           img.animated.fadeIn(src='/svg/henry-thinking.svg', alt='Henry')
           .headline= t('newpage.title')
           .subheading.mt-3= t('newpage.subtitle')
-          v-btn.mt-5(href='/e/home', large)
+          v-btn.mt-5(href='/e' + pagePath, large)
             v-icon(left) add
             span= t('newpage.create')
           v-btn.mt-2(color='blue lighten-4', href='javascript:window.history.go(-1);', large, outline)

+ 1 - 1
server/views/page.pug

@@ -13,7 +13,7 @@ block body
       created-at=page.createdAt
       updated-at=page.updatedAt
       author-name=page.authorName
-      author-id=page.authorId
+      :author-id=page.authorId
       is-published=page.isPublished
       )
       template(slot='contents')!= page.render