Compare commits

...

5 Commits

8 changed files with 3195 additions and 3264 deletions

6244
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -8,28 +8,29 @@
"lint": "vue-cli-service lint" "lint": "vue-cli-service lint"
}, },
"dependencies": { "dependencies": {
"@primer/css": "^14.1.0", "@primer/css": "^14.4.0",
"bulma": "^0.7.5", "bulma": "^0.7.5",
"event-source-polyfill": "0.0.16", "event-source-polyfill": "0.0.16",
"isomorphic-fetch": "^2.2.1", "isomorphic-fetch": "^2.2.1",
"lodash": "latest", "lodash": "^4.17.20",
"micropub-helper": "^1.4.0", "micropub-helper": "^1.6.1",
"moment": "^2.22.2", "moment": "^2.27.0",
"node-sass": "^4.14.1", "node-sass": "^4.14.1",
"rel-parser": "github:grantcodes/rel-scraper",
"rel-scraper": "github:grantcodes/rel-scraper", "rel-scraper": "github:grantcodes/rel-scraper",
"sass-loader": "^7.2.0", "sass-loader": "^7.3.1",
"tailwindcss": "1.1.4", "tailwindcss": "1.1.4",
"vue": "^2.5.17", "vue": "^2.6.11",
"vue-router": "^3.0.1", "vue-router": "^3.4.3",
"vuex": "^3.0.1" "vuex": "^3.5.1"
}, },
"devDependencies": { "devDependencies": {
"@vue/cli-plugin-babel": "^3.10.0", "@vue/cli-plugin-babel": "^3.12.1",
"@vue/cli-plugin-eslint": "^3.0.0-rc.10", "@vue/cli-plugin-eslint": "^3.12.1",
"@vue/cli-service": "^3.10.0", "@vue/cli-service": "^3.12.1",
"postcss-node-sass": "^2.1.8", "postcss-node-sass": "^2.1.8",
"postcss-scss": "^2.0.0", "postcss-scss": "^2.1.1",
"vue-template-compiler": "^2.5.17" "vue-template-compiler": "^2.6.11"
}, },
"eslintConfig": { "eslintConfig": {
"root": true, "root": true,

View File

@ -0,0 +1,43 @@
<template>
<div>
<div v-for="(target, i) in targets" :key="i" style="display: inline-block; margin: 0 3px 3px 0">
<label>
<input type="checkbox" class="is-hidden cb-target" v-model="selected" :value="target.uid"/>
<span class="tag is-light" v-text="target.name"></span>
</label>
</div>
</div>
</template>
<script>
export default {
name: 'destination-buttons',
data() {
return {
selected: [],
}
},
props: {
value: [],
targets: {}
},
mounted() {
this.selected = this.value
},
watch: {
selected(newSelection) {
this.$emit('input', newSelection)
}
}
}
</script>
<style scoped>
.tag {
cursor: pointer;
}
.cb-target:checked + .tag {
background-color: #23d160;
color: #fff;
}
</style>

View File

@ -79,7 +79,13 @@
</div> </div>
</div> </div>
<div class="field"> <div class="field">
<syndication-buttons v-model="selected" :targets="targets"/> Categories: <entry-categories v-model="categories"/>
</div>
<div class="field">
Syndication: <syndication-buttons v-model="selected" :targets="targets"/>
</div>
<div class="field">
Destination: <destination-buttons v-model="selectedDestinations" :targets="destinations"/>
</div> </div>
<div class="field"> <div class="field">
<div class="control"> <div class="control">
@ -95,11 +101,17 @@
<script> <script>
import moment from 'moment' import moment from 'moment'
import DestinationButtons from "@/components/DestinationButtons";
import EntryCategories from "@/components/EntryCategories";
import SyndicationButtons from "@/components/SyndicationButtons"; import SyndicationButtons from "@/components/SyndicationButtons";
export default { export default {
name: "Entry", name: "Entry",
components: {SyndicationButtons}, components: {
DestinationButtons,
EntryCategories,
SyndicationButtons
},
props: ['item'], props: ['item'],
data() { data() {
@ -111,7 +123,10 @@ export default {
bookmarkTitle: '', bookmarkTitle: '',
bookmarkDescription: '', bookmarkDescription: '',
targets: [], targets: [],
selected: [] selected: [],
destinations: [],
selectedDestinations: [],
categories: []
} }
}, },
@ -160,6 +175,8 @@ export default {
this.selected = [] this.selected = []
this.$store.dispatch('fetchSyndicationTargets') this.$store.dispatch('fetchSyndicationTargets')
.then(res => this.targets = res['syndicate-to']) .then(res => this.targets = res['syndicate-to'])
this.$store.dispatch('fetchDestinations')
.then(res => this.destinations = res['destination'])
}, },
bookmark() { bookmark() {
this.$store.dispatch('micropubPost', { this.$store.dispatch('micropubPost', {
@ -168,13 +185,17 @@ export default {
'bookmark-of': [this.currentItem.url], 'bookmark-of': [this.currentItem.url],
'name': [this.bookmarkTitle], 'name': [this.bookmarkTitle],
'content': [this.bookmarkDescription ], 'content': [this.bookmarkDescription ],
'mp-syndicate-to': this.selected 'category': this.categories,
'mp-syndicate-to': this.selected,
'mp-destination': this.selectedDestinations
}, },
}).then(() => { }).then(() => {
this.bookmarkTitle = ''; this.bookmarkTitle = '';
this.bookmarkDescription = ''; this.bookmarkDescription = '';
this.selected = [] this.selected = []
this.selectedDestinations = []
this.bookmarking = false this.bookmarking = false
this.categories = []
}) })
}, },
hasRef(key) { hasRef(key) {

View File

@ -0,0 +1,38 @@
<template>
<div>
<input type="text" class="input" v-model="categories">
</div>
</template>
<script>
export default {
name: "EntryCategories",
props: {
'value': {
type: Array,
default: []
}
},
data() {
return {
categories: ''
}
},
mounted() {
this.categories = this.value.join(" ")
},
watch: {
categories() {
let words = this.categories.split(/\s+/).filter(value => value.length !== 0)
this.$emit('input', words)
}
}
}
</script>
<style scoped>
</style>

View File

@ -12,8 +12,16 @@
</div> </div>
</div> </div>
<div class="field"> <div class="field">
Categories: <entry-categories v-model="categories" />
</div>
<div class="field">
Syndication:
<syndication-buttons v-model="selectedTargets" :targets="targets"/> <syndication-buttons v-model="selectedTargets" :targets="targets"/>
</div> </div>
<div class="field">
Destinations:
<destination-buttons v-model="selectedDestinations" :targets="destinations"/>
</div>
<div class="level"> <div class="level">
<div class="level-left"> <div class="level-left">
<div class="level-item"> <div class="level-item">
@ -36,22 +44,32 @@
</template> </template>
<script> <script>
import DestinationButtons from "@/components/DestinationButtons";
import EntryCategories from "@/components/EntryCategories";
import SyndicationButtons from "@/components/SyndicationButtons"; import SyndicationButtons from "@/components/SyndicationButtons";
export default { export default {
name: "NewPost", name: "NewPost",
components:{ components:{
SyndicationButtons DestinationButtons,
EntryCategories,
SyndicationButtons,
}, },
data() { data() {
return { return {
newPost: '', newPost: '',
targets: [], targets: [],
selectedTargets: [] selectedTargets: [],
destinations: [],
selectedDestinations: [],
categories: []
} }
}, },
mounted() { mounted() {
this.$store.dispatch('fetchSyndicationTargets') this.$store.dispatch('fetchSyndicationTargets')
.then(res => this.targets = res['syndicate-to']) .then(res => this.targets = res['syndicate-to'])
this.$store.dispatch('fetchDestinations')
.then(res => this.destinations = res['destination'])
}, },
methods: { methods: {
post() { post() {
@ -59,10 +77,15 @@
'type': ['h-entry'], 'type': ['h-entry'],
'properties': { 'properties': {
'content': [this.newPost], 'content': [this.newPost],
'category': this.categories,
'mp-syndicate-to': this.selectedTargets, 'mp-syndicate-to': this.selectedTargets,
'mp-destination': this.selectedDestinations,
}, },
}).then(() => { }).then(() => {
this.newPost = ''; this.newPost = ''
this.categories = []
this.selectedTargets = []
this.selectedDestinations = []
this.$emit('close') this.$emit('close')
}) })
}, },

View File

@ -25,7 +25,7 @@ export default {
}, },
watch: { watch: {
selected(newSelection) { selected(newSelection) {
this.$emit('update', newSelection) this.$emit('input', newSelection)
} }
} }
} }

View File

@ -18,7 +18,7 @@ export default new Vuex.Store({
microsubEndpoint: '/microsub', microsubEndpoint: '/microsub',
channelCreatorIsOpen: false, channelCreatorIsOpen: false,
eventSource: null, eventSource: null,
globalTimeline: {items: [{name:'Testing the global timeline'}]} globalTimeline: {items: [{name: 'Testing the global timeline'}]}
}; };
let loginData = JSON.parse(window.localStorage.getItem('login_data')) let loginData = JSON.parse(window.localStorage.getItem('login_data'))
if (loginData) { if (loginData) {
@ -108,12 +108,39 @@ export default new Vuex.Store({
state.eventSource.addEventListener('new item in channel', evt => { state.eventSource.addEventListener('new item in channel', evt => {
// eslint-disable-next-line // eslint-disable-next-line
console.log(evt) console.log(evt)
let d = JSON.parse(evt.data) let msg = JSON.parse(evt.data)
let channel = _.find(state.channels, item => item.uid === d.uid) let channel = _.find(state.channels, item => item.uid === msg.uid)
if (channel) { if (channel) {
channel.unread = d.unread channel.unread = msg.unread
} }
}) })
state.eventSource.addEventListener('new channel', evt => {
// eslint-disable-next-line
console.log(evt)
let msg = JSON.parse(evt.data)
let channel = _.find(state.channels, it => it.uid === msg.channel.uid)
if (!channel) {
state.channels.push(msg.channel)
}
})
state.eventSource.addEventListener('update channel', evt => {
// eslint-disable-next-line
console.log(evt)
let msg = JSON.parse(evt.data)
let channel = _.find(state.channels, it => it.uid === msg.channel.uid)
if (channel) {
channel.name = msg.channel.name
}
})
state.eventSource.addEventListener('delete channel', evt => {
// eslint-disable-next-line
console.log(evt)
let msg = JSON.parse(evt.data)
state.channels = _.remove(state.channels, it => it.uid === msg.uid)
})
} }
}, },
@ -166,7 +193,7 @@ export default new Vuex.Store({
markRead(x, {channel, entry}) { markRead(x, {channel, entry}) {
let entries = ''; let entries = '';
if (Array.isArray(entry)) { if (Array.isArray(entry)) {
entries = _(entry).map(uid => '&entry[]='+encodeURIComponent(uid)).join("") entries = _(entry).map(uid => '&entry[]=' + encodeURIComponent(uid)).join("")
} else { } else {
entries = '&entry=' + encodeURIComponent(entry) entries = '&entry=' + encodeURIComponent(entry)
} }
@ -178,12 +205,18 @@ export default new Vuex.Store({
} }
}) })
}, },
fetchSyndicationTargets() { configQuery: function (key) {
let micropub = new Micropub({ let micropub = new Micropub({
token: this.state.access_token, token: this.state.access_token,
micropubEndpoint: this.state.micropubEndpoint micropubEndpoint: this.state.micropubEndpoint
}) })
return micropub.query('syndicate-to') return micropub.query(key)
},
fetchSyndicationTargets() {
return this.configQuery('syndicate-to')
},
fetchDestinations() {
return this.configQuery('destination');
}, },
micropubPost(_, mf2post) { micropubPost(_, mf2post) {
let micropub = new Micropub({ let micropub = new Micropub({