feat: Separate title from body (#1216)

* first pass at updating all Time components each second

* fix a couple date variable typos

* use class style state management instead of hooks

* wip: Separate title from body

* address feedback

* test: Remove unused test

* feat: You in publishing info language
fix: Removal of secondary headings

* After much deliberation… a migration is needed for this to be reliable

* fix: Export to work with new title structure

* fix: Untitled

* fix: Consistent spacing of first editor node

* fix: Emoji in title handling

* fix: Time component not updating for new props

* chore: Add createdAt case

* fix: Conflict after merging new TOC

* PR feedback

* lint

* fix: Heading level adjustment

Co-authored-by: Taylor Lapeyre <taylorlapeyre@gmail.com>
This commit is contained in:
Tom Moor
2020-04-05 15:07:34 -07:00
committed by GitHub
parent a0e73bf4c2
commit 9338a54fe0
19 changed files with 241 additions and 145 deletions

View File

@@ -17,7 +17,8 @@ import Revision from './Revision';
const Op = Sequelize.Op;
const Markdown = new MarkdownSerializer();
const URL_REGEX = /^[0-9a-zA-Z-_~]*-([a-zA-Z0-9]{10,15})$/;
const DEFAULT_TITLE = 'Untitled';
export const DOCUMENT_VERSION = 1;
slug.defaults.mode = 'rfc3986';
const slugify = text =>
@@ -38,6 +39,7 @@ const createRevision = (doc, options = {}) => {
text: doc.text,
userId: doc.lastModifiedById,
editorVersion: doc.editorVersion,
version: doc.version,
documentId: doc.id,
},
{
@@ -50,16 +52,19 @@ const createUrlId = doc => {
return (doc.urlId = doc.urlId || randomstring.generate(10));
};
const beforeCreate = async doc => {
doc.version = DOCUMENT_VERSION;
return beforeSave(doc);
};
const beforeSave = async doc => {
const { emoji, title } = parseTitle(doc.text);
const { emoji } = parseTitle(doc.text);
// emoji in the title is split out for easier display
doc.emoji = emoji;
// ensure documents have a title
if (!title) {
doc.title = DEFAULT_TITLE;
}
doc.title = doc.title || '';
// add the current user as a collaborator on this doc
if (!doc.collaboratorIds) doc.collaboratorIds = [];
@@ -92,6 +97,7 @@ const Document = sequelize.define(
},
},
},
version: DataTypes.SMALLINT,
editorVersion: DataTypes.STRING,
text: DataTypes.TEXT,
isWelcome: { type: DataTypes.BOOLEAN, defaultValue: false },
@@ -105,7 +111,7 @@ const Document = sequelize.define(
paranoid: true,
hooks: {
beforeValidate: createUrlId,
beforeCreate: beforeSave,
beforeCreate: beforeCreate,
beforeUpdate: beforeSave,
afterCreate: createRevision,
afterUpdate: createRevision,
@@ -427,6 +433,26 @@ Document.addHook('afterCreate', async model => {
// Instance methods
Document.prototype.toMarkdown = function() {
const text = unescape(this.text);
if (this.version) {
return `# ${this.title}\n\n${text}`;
}
return text;
};
Document.prototype.migrateVersion = function() {
// migrate from document version 0 -> 1 means removing the title from the
// document text attribute.
if (!this.version) {
this.text = this.text.replace(/^#\s(.*)\n/, '');
this.version = 1;
return this.save({ silent: true, hooks: false });
}
};
// Note: This method marks the document and it's children as deleted
// in the database, it does not permanantly delete them OR remove
// from the collection structure.