Renote visibility (#3290)

This commit is contained in:
MeiMei 2018-11-17 03:25:48 +09:00 committed by syuilo
parent db657c2a62
commit 0bf54b3ff6
5 changed files with 52 additions and 16 deletions

View File

@ -788,6 +788,7 @@ desktop/views/components/renote-form.vue:
quote: "引用する..." quote: "引用する..."
cancel: "キャンセル" cancel: "キャンセル"
renote: "Renote" renote: "Renote"
renote-home: "Renote (ホーム)"
reposting: "しています..." reposting: "しています..."
success: "Renoteしました" success: "Renoteしました"
failure: "Renoteに失敗しました" failure: "Renoteに失敗しました"

View File

@ -5,7 +5,8 @@
<footer> <footer>
<a class="quote" v-if="!quote" @click="onQuote">{{ $t('quote') }}</a> <a class="quote" v-if="!quote" @click="onQuote">{{ $t('quote') }}</a>
<ui-button class="button cancel" inline @click="cancel">{{ $t('cancel') }}</ui-button> <ui-button class="button cancel" inline @click="cancel">{{ $t('cancel') }}</ui-button>
<ui-button class="button ok" inline primary @click="ok" :disabled="wait">{{ wait ? this.$t('reposting') : this.$t('renote') }}</ui-button> <ui-button class="button home" inline :primary="visibility != 'public'" @click="ok('home')" :disabled="wait">{{ wait ? this.$t('reposting') : this.$t('renote-home') }}</ui-button>
<ui-button class="button ok" inline :primary="visibility == 'public'" @click="ok('public')" :disabled="wait">{{ wait ? this.$t('reposting') : this.$t('renote') }}</ui-button>
</footer> </footer>
</template> </template>
<template v-if="quote"> <template v-if="quote">
@ -24,14 +25,16 @@ export default Vue.extend({
data() { data() {
return { return {
wait: false, wait: false,
quote: false quote: false,
visibility: this.$store.state.settings.defaultNoteVisibility
}; };
}, },
methods: { methods: {
ok() { ok(v: string) {
this.wait = true; this.wait = true;
this.$root.api('notes/create', { this.$root.api('notes/create', {
renoteId: this.note.id renoteId: this.note.id,
visibility: v || this.visibility
}).then(data => { }).then(data => {
this.$emit('posted'); this.$emit('posted');
this.$notify(this.$t('success')); this.$notify(this.$t('success'));
@ -81,7 +84,11 @@ export default Vue.extend({
height 40px height 40px
&.cancel &.cancel
right 280px
&.home
right 148px right 148px
font-size 13px
&.ok &.ok
right 16px right 16px

View File

@ -35,17 +35,11 @@ export default async function(resolver: Resolver, actor: IRemoteUser, activity:
log(`Creating the (Re)Note: ${uri}`); log(`Creating the (Re)Note: ${uri}`);
//#region Visibility //#region Visibility
let visibility = 'public'; const visibility = getVisibility(activity.to, activity.cc, actor);
let visibleUsers: IUser[] = []; let visibleUsers: IUser[] = [];
if (!note.to.includes('https://www.w3.org/ns/activitystreams#Public')) { if (visibility == 'specified') {
if (note.cc.includes('https://www.w3.org/ns/activitystreams#Public')) { visibleUsers = await Promise.all(note.to.map(uri => resolvePerson(uri)));
visibility = 'home';
} else if (note.to.includes(`${actor.uri}/followers`)) { // TODO: person.followerと照合するべき
visibility = 'followers';
} else {
visibility = 'specified';
visibleUsers = await Promise.all(note.to.map(uri => resolvePerson(uri)));
}
} }
//#endergion //#endergion
@ -57,3 +51,22 @@ export default async function(resolver: Resolver, actor: IRemoteUser, activity:
uri uri
}); });
} }
type visibility = 'public' | 'home' | 'followers' | 'specified' | 'private';
function getVisibility(to: string[], cc: string[], actor: IRemoteUser): visibility {
const PUBLIC = 'https://www.w3.org/ns/activitystreams#Public';
to = to || [];
cc = cc || [];
if (to.includes(PUBLIC)) {
return 'public';
} else if (cc.includes(PUBLIC)) {
return 'home';
} else if (to.includes(`${actor.uri}/followers`)) {
return 'followers';
} else {
return 'specified';
}
}

View File

@ -4,13 +4,26 @@ import { INote } from '../../../models/note';
export default (object: any, note: INote) => { export default (object: any, note: INote) => {
const attributedTo = `${config.url}/users/${note.userId}`; const attributedTo = `${config.url}/users/${note.userId}`;
let to: string[] = [];
let cc: string[] = [];
if (note.visibility == 'public') {
to = ['https://www.w3.org/ns/activitystreams#Public'];
cc = [`${attributedTo}/followers`];
} else if (note.visibility == 'home') {
to = [`${attributedTo}/followers`];
cc = ['https://www.w3.org/ns/activitystreams#Public'];
} else {
return null;
}
return { return {
id: `${config.url}/notes/${note._id}/activity`, id: `${config.url}/notes/${note._id}/activity`,
actor: `${config.url}/users/${note.userId}`, actor: `${config.url}/users/${note.userId}`,
type: 'Announce', type: 'Announce',
published: note.createdAt.toISOString(), published: note.createdAt.toISOString(),
to: ['https://www.w3.org/ns/activitystreams#Public'], to,
cc: [attributedTo, `${attributedTo}/followers`], cc,
object object
}; };
}; };

View File

@ -2,6 +2,8 @@ import config from '../../../config';
import * as uuid from 'uuid'; import * as uuid from 'uuid';
export default (x: any) => { export default (x: any) => {
if (x == null) return null;
if (x !== null && typeof x === 'object' && x.id == null) { if (x !== null && typeof x === 'object' && x.id == null) {
x.id = `${config.url}/${uuid.v4()}`; x.id = `${config.url}/${uuid.v4()}`;
} }