|
|
|
|
@ -6,31 +6,122 @@ import { ReactiveVar } from 'meteor/reactive-var'; |
|
|
|
|
import { ReactiveDict } from 'meteor/reactive-dict'; |
|
|
|
|
|
|
|
|
|
import { DateFormat } from '../../../lib/client'; |
|
|
|
|
import { canDeleteMessage, getURL, handleError, t } from '../../../utils/client'; |
|
|
|
|
import { canDeleteMessage, getURL, handleError, t, APIClient } from '../../../utils/client'; |
|
|
|
|
import { popover, modal } from '../../../ui-utils/client'; |
|
|
|
|
|
|
|
|
|
const roomFiles = new Mongo.Collection('room_files'); |
|
|
|
|
import { Rooms, Messages } from '../../../models/client'; |
|
|
|
|
import { upsertMessageBulk } from '../../../ui-utils/client/lib/RoomHistoryManager'; |
|
|
|
|
|
|
|
|
|
const LIST_SIZE = 50; |
|
|
|
|
const DEBOUNCE_TIME_TO_SEARCH_IN_MS = 500; |
|
|
|
|
|
|
|
|
|
const getFileUrl = (attachments) => { |
|
|
|
|
if (!attachments || !attachments.length) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
return attachments[0].image_url || attachments[0].audio_url || attachments[0].video_url; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const mountFileObject = (message) => ({ |
|
|
|
|
...message.file, |
|
|
|
|
rid: message.rid, |
|
|
|
|
user: message.u, |
|
|
|
|
description: message.attachments && message.attachments[0].description, |
|
|
|
|
url: getFileUrl(message.attachments), |
|
|
|
|
_updatedAt: message.attachments && message.attachments[0].ts, |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const roomTypes = { |
|
|
|
|
c: 'channels', |
|
|
|
|
d: 'im', |
|
|
|
|
p: 'groups', |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const fields = { |
|
|
|
|
_id: 1, |
|
|
|
|
userId: 1, |
|
|
|
|
rid: 1, |
|
|
|
|
name: 1, |
|
|
|
|
description: 1, |
|
|
|
|
type: 1, |
|
|
|
|
url: 1, |
|
|
|
|
uploadedAt: 1, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
Template.uploadedFilesList.onCreated(function() { |
|
|
|
|
const { rid } = Template.currentData(); |
|
|
|
|
const room = Rooms.findOne({ _id: rid }); |
|
|
|
|
this.searchText = new ReactiveVar(null); |
|
|
|
|
|
|
|
|
|
this.roomFiles = new ReactiveVar([]); |
|
|
|
|
this.files = new Mongo.Collection(null); |
|
|
|
|
this.state = new ReactiveDict({ |
|
|
|
|
limit: LIST_SIZE, |
|
|
|
|
hasMore: true, |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const messageQuery = { |
|
|
|
|
rid, |
|
|
|
|
'file._id': { $exists: true }, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
this.cursor = Messages.find(messageQuery).observe({ |
|
|
|
|
added: ({ ...message }) => { |
|
|
|
|
this.files.upsert(message.file._id, mountFileObject(message)); |
|
|
|
|
}, |
|
|
|
|
changed: ({ ...message }) => { |
|
|
|
|
this.files.upsert(message.file._id, mountFileObject(message)); |
|
|
|
|
}, |
|
|
|
|
removed: ({ ...message }) => { |
|
|
|
|
this.files.remove(message.file._id); |
|
|
|
|
}, |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const loadFiles = _.debounce(async (query, limit) => { |
|
|
|
|
this.state.set('loading', true); |
|
|
|
|
|
|
|
|
|
const { files } = await APIClient.v1.get(`${ roomTypes[room.t] }.files?roomId=${ query.rid }&limit=${ limit }&query=${ JSON.stringify(query) }&fields=${ JSON.stringify(fields) }`); |
|
|
|
|
|
|
|
|
|
upsertMessageBulk({ msgs: files }, this.files); |
|
|
|
|
|
|
|
|
|
this.state.set({ |
|
|
|
|
hasMore: this.state.get('limit') <= files.length, |
|
|
|
|
loading: false, |
|
|
|
|
}); |
|
|
|
|
}, DEBOUNCE_TIME_TO_SEARCH_IN_MS); |
|
|
|
|
|
|
|
|
|
const query = { |
|
|
|
|
rid, |
|
|
|
|
complete: true, |
|
|
|
|
uploading: false, |
|
|
|
|
_hidden: { |
|
|
|
|
$ne: true, |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
this.autorun(() => { |
|
|
|
|
this.searchText.get(); |
|
|
|
|
this.state.set('limit', LIST_SIZE); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
this.autorun(() => { |
|
|
|
|
const ready = this.subscribe('roomFilesWithSearchText', rid, this.searchText.get(), this.state.get('limit'), () => this.state.set('hasMore', this.state.get('limit') <= roomFiles.find({ rid }).count())).ready(); |
|
|
|
|
this.state.set('loading', !ready); |
|
|
|
|
const limit = this.state.get('limit'); |
|
|
|
|
const searchText = this.searchText.get(); |
|
|
|
|
if (!searchText) { |
|
|
|
|
return loadFiles(query, limit); |
|
|
|
|
} |
|
|
|
|
this.files.remove({}); |
|
|
|
|
const regex = { $regex: searchText, $options: 'i' }; |
|
|
|
|
return loadFiles({ ...query, name: regex }, limit); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
Template.mentionsFlexTab.onDestroyed(function() { |
|
|
|
|
this.cursor.stop(); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
Template.uploadedFilesList.helpers({ |
|
|
|
|
files() { |
|
|
|
|
return roomFiles.find({ rid: this.rid }, { sort: { uploadedAt: -1 } }); |
|
|
|
|
const instance = Template.instance(); |
|
|
|
|
return instance.files.find({}, { limit: instance.state.get('limit') }); |
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
url() { |
|
|
|
|
|