diff --git a/server.js b/server.js index 81af978..4a40ff4 100644 --- a/server.js +++ b/server.js @@ -4,11 +4,17 @@ const { vueRenderer } = require('@doweb/vuexpress') const app = express() +// ALlow URLencoded API +app.use(bodyParser.urlencoded({ + extended: false +})) + // Allow JSON API app.use(bodyParser('json')) // Enable static files app.use(express.static('public')) +app.use(express.static('static')) // Set up VueXpress let options = { @@ -30,7 +36,65 @@ app.use(renderer) // Views app.get('/', (req, res) => { - res.render('index', { message: 'Hey, welcome to Seance!' }) + res.render('index') +}) + +app.get('/fetch/', (req, res) => { + res.redirect('/') +}) + +app.post('/fetch/', (req, res) => { + var json + var post + + try { + json = JSON.parse(req.body.data) + } catch (err) { + console.log(err) + } + + if (json) { + post = json.payload.value + console.log(post) + + // set author + post.author = post.displayAuthor + + // If the author's not available, get it from somewhere else + // function courtesy mediumexporter + let authors = [] + if (json.payload.references && json.payload.references.User) { + Object.keys(json.payload.references.User).forEach(k => { + let u = json.payload.references.User[k] + authors.push({ + name: u.name, + username: u.username, + userId: u.userId + }) + }) + post.authors = authors + + if (!post.author) { + post.author = authors[0].name + } + } + + // set featured image + if (post.virtuals.previewImage) { + post.featuredImage = 'https://cdn-images-1.medium.com/max/800/' + post.virtuals.previewImage.imageId + } + } + + // render the final post + res.render('fetch-medium', { + post: { + title: post.title, + subtitle: post.content.subtitle, + author: post.author, + featuredImage: post.featuredImage, + mediumUrl: post.mediumUrl, + } + }) }) app.get('/api/', (req, res) => { diff --git a/static/bookmarklet.js b/static/bookmarklet.js new file mode 100644 index 0000000..10dc1e4 --- /dev/null +++ b/static/bookmarklet.js @@ -0,0 +1,77 @@ +(() => { + + const baseUrl = 'http://localhost:4000' + + function resetTitle() { + document.title = document.title.replace('[Loading...] ', '') + } + + // Check that we're not on a Seance page + if (window.location.href.startsWith(baseUrl)) { + alert('That\'s not how to do it, silly!\n\nYou\'re supposed to BOOKMARK this link (by dragging it to the bookmarks bar or right-clicking and saying "save bookmark").\n\nWait till you\'re on a Medium page; don\'t try to start clicking on it right now ;)') + + // Reset title + resetTitle() + return + } + + // Keep the user engaged with a nice bannery message + + var d1 = document.createElement('div') + d1.style="position: absolute; top:0; right: 0; left: 0; background-color: turquoise; min-height: 2em; z-index: 100; text-align: center;" + + var p1 = document.createElement('p') + p1.innerHTML = 'Seance loading in progress...' + p1.style='font-size: 2rem; margin: 2rem; color: white;' + + d1.appendChild(p1) + document.body.appendChild(d1) + + // Form sending function + function handleJSON(data) { + try { + data = JSON.parse(data.slice(data.indexOf('{'))) + } catch (err) { + alert('Something went wrong fetching the post. Please make sure you\'re on a Medium site and try again.') + + // Hide the loading screen + d1.parentElement.removeChild(d1) + + // Reset the title + resetTitle() + + // Give up + return + } + + // Create a form to hold the data + var f = document.createElement('form') + f.action=baseUrl + '/fetch/' + f.method='post' + + // Create hidden input to hold data + i = document.createElement('input') + i.name='data' + i.type='hidden' + i.value=JSON.stringify(data) + + // Assign children to parents + f.appendChild(i) + document.body.appendChild(f) + + // Submit the form + f.submit() + } + + // fetch the XML + var r = new XMLHttpRequest() + r.open('GET', window.location + '?format=json') + r.onreadystatechange = function () { + if (r.readyState == 4 && r.status == 200) { + handleJSON(r.responseText) + } + } + r.setRequestHeader("Content-Type", "application/json;charset=utf-8") + r.send(null) + +})() diff --git a/views/fetch-medium.vue b/views/fetch-medium.vue new file mode 100644 index 0000000..b68d050 --- /dev/null +++ b/views/fetch-medium.vue @@ -0,0 +1,79 @@ + + + + + diff --git a/views/index.vue b/views/index.vue index 808ecd0..51b75c0 100644 --- a/views/index.vue +++ b/views/index.vue @@ -25,9 +25,12 @@ -
+

{{ title }}

-

{{ message }}

+
+ +

or, use the bookmarklet Add to Seance

+
@@ -39,8 +42,8 @@ data () { return { title: 'Seance', - message: 'Hi there', user: null, + host: 'http://localhost:4000', } } }