Compare commits

..

No commits in common. "7d8205930afd9d05ecf4367bc0ebea982692b213" and "450c8f114b65d1ea701488762cbaa214e488e6b8" have entirely different histories.

5 changed files with 114 additions and 108 deletions

View File

@ -83,12 +83,4 @@ export class Channel {
comment: 'The count of users.', comment: 'The count of users.',
}) })
public usersCount: number; public usersCount: number;
constructor(data: Partial<Channel>) {
if (data == null) return;
for (const [k, v] of Object.entries(data)) {
(this as any)[k] = v;
}
}
} }

View File

@ -54,19 +54,17 @@ export default define(meta, paramDef, async (ps, user) => {
} }
} }
const keyPair = await genRsaKeyPair(4096); const keyPair = genRsaKeyPair(4096);
let channel!: Channel;
await db.transaction(async transactionalEntityManager => { await db.transaction(async transactionalEntityManager => {
channel = await transactionalEntityManager.save(new Channel({ const channel = await transactionalEntityManager.insert(Channel, {
id: genId(), id: genId(),
createdAt: new Date(), createdAt: new Date(),
userId: user.id, userId: user.id,
name: ps.name, name: ps.name,
description: ps.description || null, description: ps.description || null,
bannerId: banner ? banner.id : null, bannerId: banner ? banner.id : null,
})); }).then(x => Channels.findOneByOrFail(x.identifiers[0]));
await transactionalEntityManager.insert(ChannelKeypair, { await transactionalEntityManager.insert(ChannelKeypair, {
publicKey: keyPair.publicKey, publicKey: keyPair.publicKey,

View File

@ -159,10 +159,12 @@ const menu = computed(() => [{
} }
}]); }]);
const lists = ref([]); const { lists, antennas, followedChannels, featuredChannels } = toRefs({
const antennas = ref([]); lists: [],
const followedChannels = ref([]); antennas: [],
const featuredChannels = ref([]); followedChannels: [],
featuredChannels: [],
});
function getSidebarContent() { function getSidebarContent() {
os.api('users/lists/list').then(newLists => { os.api('users/lists/list').then(newLists => {

View File

@ -4,16 +4,14 @@
<div v-if="date" class="info"> <div v-if="date" class="info">
<MkInfo>{{ i18n.ts.showingPastTimeline }} <button class="_textButton clear" @click="timetravel()">{{ i18n.ts.clear }}</button></MkInfo> <MkInfo>{{ i18n.ts.showingPastTimeline }} <button class="_textButton clear" @click="timetravel()">{{ i18n.ts.clear }}</button></MkInfo>
</div> </div>
<div class="body" class="{ channel: channelId }"> <div class="top">
<div class="postform">
<XPostForm/> <XPostForm/>
</div> </div>
<div ref="scroller" class="tl"> <div ref="body" class="tl">
<div v-if="queue > 0" class="new" :style="{ width: width + 'px', top: top + 'px' }"><button class="_buttonPrimary" @click="goTop()">{{ i18n.ts.newNoteRecived }}</button></div> <div v-if="queue > 0" class="new" :style="{ width: width + 'px', top: top + 'px' }"><button class="_buttonPrimary" @click="goTop()">{{ i18n.ts.newNoteRecived }}</button></div>
<XNotes ref="tl" class="tl" :pagination="pagination" @queue="queueUpdated"/> <XNotes ref="tl" class="tl" :pagination="pagination" @queue="queueUpdated"/>
</div> </div>
</div> </div>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -30,12 +28,10 @@ import { defaultStore } from '@/store';
import { i18n } from '@/i18n'; import { i18n } from '@/i18n';
type Props = { type Props = {
tlSrc: string; src: string;
channelId?: string;
}; };
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
tlSrc: 'home', src: 'home',
channelId: null,
}); });
const emit = defineEmits(['note']); const emit = defineEmits(['note']);
@ -55,7 +51,7 @@ const typers = ref([]);
const date = ref(null); const date = ref(null);
const tl = ref(); const tl = ref();
const scroller = ref(); const body = ref();
definePageMetadata(computed(() => ({ definePageMetadata(computed(() => ({
title: i18n.ts.timeline, title: i18n.ts.timeline,
@ -86,7 +82,8 @@ const connection2 = ref(null);
const endpoint = ref(null); const endpoint = ref(null);
watchEffect((onCleanup) => { watchEffect((onCleanup) => {
if (props.tlSrc == 'home') { console.log(props.src, defaultStore.state.numberOfPageCache);
if (props.src == 'home') {
endpoint.value = 'notes/timeline'; endpoint.value = 'notes/timeline';
connection.value = markRaw(stream.useChannel('homeTimeline')); connection.value = markRaw(stream.useChannel('homeTimeline'));
connection.value.on('note', prepend); connection.value.on('note', prepend);
@ -94,23 +91,22 @@ watchEffect((onCleanup) => {
connection2.value = markRaw(stream.useChannel('main')); connection2.value = markRaw(stream.useChannel('main'));
connection2.value.on('follow', onChangeFollowing); connection2.value.on('follow', onChangeFollowing);
connection2.value.on('unfollow', onChangeFollowing); connection2.value.on('unfollow', onChangeFollowing);
} else if (props.tlSrc == 'local') { } else if (props.src == 'local') {
endpoint.value = 'notes/local-timeline'; endpoint.value = 'notes/local-timeline';
connection.value = markRaw(stream.useChannel('localTimeline')); connection.value = markRaw(stream.useChannel('localTimeline'));
connection.value.on('note', prepend); connection.value.on('note', prepend);
} else if (props.tlSrc == 'social') { } else if (props.src == 'social') {
endpoint.value = 'notes/hybrid-timeline'; endpoint.value = 'notes/hybrid-timeline';
connection.value = markRaw(stream.useChannel('hybridTimeline')); connection.value = markRaw(stream.useChannel('hybridTimeline'));
connection.value.on('note', prepend); connection.value.on('note', prepend);
} else if (props.tlSrc == 'global') { } else if (props.src == 'global') {
endpoint.value = 'notes/global-timeline'; endpoint.value = 'notes/global-timeline';
connection.value = markRaw(stream.useChannel('globalTimeline')); connection.value = markRaw(stream.useChannel('globalTimeline'));
connection.value.on('note', prepend); connection.value.on('note', prepend);
} else if (props.tlSrc == 'channel') {
} }
onCleanup(() => { onCleanup(() => {
console.log('cleaning');
connection.value.dispose(); connection.value.dispose();
if (connection2.value) connection2.value.dispose(); if (connection2.value) connection2.value.dispose();
}); });
@ -127,20 +123,20 @@ const pagination = computed(() => ({
function focus() { function focus() {
scroller.value.focus(); body.value.focus();
}; };
function goTop() { function goTop() {
const container = getScrollContainer(scroller.value); const container = getScrollContainer(body.value);
container.scrollTop = 0; container.scrollTop = 0;
}; };
function queueUpdated(q) { function queueUpdated(q) {
if (scroller.value.offsetWidth !== 0) { if (body.value.offsetWidth !== 0) {
const rect = scroller.value.getBoundingClientRect(); const rect = body.value.getBoundingClientRect();
this.width = scroller.value.offsetWidth; this.width = body.value.offsetWidth;
top.value = rect.top; top.value = rect.top;
bottom.value = scroller.value.offsetHeight; bottom.value = body.value.offsetHeight;
} }
queue.value = q; queue.value = q;
}; };
@ -162,11 +158,11 @@ function timetravel(target?: Date) {
padding: 16px 16px 0 16px; padding: 16px 16px 0 16px;
} }
.postform { > .top {
padding: 16px 16px 0 16px; padding: 16px 16px 0 16px;
} }
.bottom { > .bottom {
padding: 0 16px 16px 16px; padding: 0 16px 16px 16px;
position: relative; position: relative;

View File

@ -7,81 +7,99 @@
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts">
import { ref, reactive, computed } from 'vue'; import { defineComponent } from 'vue';
import * as os from '@/os'; import * as os from '@/os';
import copyToClipboard from '@/scripts/copy-to-clipboard'; import copyToClipboard from '@/scripts/copy-to-clipboard';
import { i18n } from '@/i18n';
import { useRouter } from '@/router'; import { useRouter } from '@/router';
import { url as baseUrl } from '@/config'; import { url } from '@/config';
const router = useRouter(); const router = useRouter();
const history = reactive([]);
const path = ref(null);
const component = ref(null);
const props = ref({});
const emit = defineEmits(['open', 'close']); export default defineComponent({
components: {
},
const url = computed(() => baseUrl + path.value) provide() {
return {
navHook: (path) => {
this.navigate(path);
}
};
},
const pageInfo = null; data() {
return {
path: null,
component: null,
props: {},
pageInfo: null,
history: [],
};
},
function navigate(path, record = true) { computed: {
if (record && path.value) history.push(path.value); url(): string {
path.value = path; return url + this.path;
const { component: newComponent, props: newProps } = router.resolve(path); }
component.value = newComponent; },
props.value = newProps;
emit('open');
}
function back() { methods: {
navigate(history.pop(), false); navigate(path, record = true) {
} if (record && this.path) this.history.push(this.path);
this.path = path;
const { component, props } = resolve(path);
this.component = component;
this.props = props;
this.$emit('open');
},
function close() { back() {
path.value = null; this.navigate(this.history.pop(), false);
component.value = null; },
props.value = {};
emit('close');
}
function onContextmenu(e) { close() {
this.path = null;
this.component = null;
this.props = {};
this.$emit('close');
},
onContextmenu(e) {
os.contextMenu([{ os.contextMenu([{
type: 'label', type: 'label',
text: this.path, text: this.path,
}, { }, {
icon: 'fas fa-expand-alt', icon: 'fas fa-expand-alt',
text: i18n.ts.showInPage, text: this.$ts.showInPage,
action: () => { action: () => {
router.push(path); router.push(this.path);
close(); this.close();
} }
}, { }, {
icon: 'fas fa-window-maximize', icon: 'fas fa-window-maximize',
text: i18n.ts.openInWindow, text: this.$ts.openInWindow,
action: () => { action: () => {
os.pageWindow(path); os.pageWindow(this.path);
close(); this.close();
} }
}, null, { }, null, {
icon: 'fas fa-external-link-alt', icon: 'fas fa-external-link-alt',
text: i18n.ts.openInNewTab, text: this.$ts.openInNewTab,
action: () => { action: () => {
window.open(url, '_blank'); window.open(this.url, '_blank');
close(); this.close();
} }
}, { }, {
icon: 'fas fa-link', icon: 'fas fa-link',
text: i18n.ts.copyLink, text: this.$ts.copyLink,
action: () => { action: () => {
copyToClipboard(url); copyToClipboard(this.url);
} }
}], e); }], e);
} }
}
defineExpose({ navHook: navigate }); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>