Progress
new MediaAttachment video style :playable for mp4 to make videojs work with multiple files, hiding albums, hiding bookmark collections. may need tweaks on mediaattachment for mov and other formats : todo :
This commit is contained in:
@@ -47,7 +47,7 @@ export const fetchAlbums = (accountId) => (dispatch, getState) => {
|
||||
|
||||
dispatch(fetchAlbumsRequest(accountId))
|
||||
|
||||
api(getState).get(`/api/v1/albums/find_by_account/${accountId}`).then((response) => {
|
||||
api(getState).get(`/api/v1/album_lists/${accountId}`).then((response) => {
|
||||
const next = getLinks(response).refs.find(link => link.rel === 'next')
|
||||
dispatch(fetchAlbumsSuccess(response.data, accountId, next ? next.uri : null))
|
||||
}).catch((error) => {
|
||||
@@ -119,7 +119,7 @@ const expandAlbumsFail = (accountId, error) => ({
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const createAlbum = (title, description, visibility) => (dispatch, getState) => {
|
||||
export const createAlbum = (title, description) => (dispatch, getState) => {
|
||||
if (!me || !title) return
|
||||
|
||||
dispatch(createAlbumRequest())
|
||||
@@ -127,7 +127,6 @@ export const createAlbum = (title, description, visibility) => (dispatch, getSta
|
||||
api(getState).post('/api/v1/albums', {
|
||||
title,
|
||||
description,
|
||||
visibility,
|
||||
}).then((response) => {
|
||||
dispatch(createAlbumSuccess(response.data))
|
||||
}).catch((error) => {
|
||||
|
||||
@@ -21,13 +21,17 @@ class Album extends React.PureComponent {
|
||||
|
||||
render() {
|
||||
const {
|
||||
account,
|
||||
album,
|
||||
isAddable,
|
||||
} = this.props
|
||||
|
||||
const title = isAddable ? 'New album' : 'Album title'
|
||||
const subtitle = isAddable ? '' : '10 Items'
|
||||
const to = isAddable ? undefined : `/photos`
|
||||
|
||||
if (!isAddable && (!album || !account)) return null
|
||||
|
||||
const title = isAddable ? 'New album' : album.get('title')
|
||||
const subtitle = isAddable ? '' : `${album.get('count')} Items`
|
||||
const to = isAddable ? undefined : `/${account.get('username')}/albums/${album.get('id')}`
|
||||
const albumImageUrl = !!album ? album.getIn(['cover', 'preview_url'], null) : null
|
||||
|
||||
return (
|
||||
<div className={[_s.d, _s.minW162PX, _s.px5, _s.flex1].join(' ')}>
|
||||
@@ -40,8 +44,17 @@ class Album extends React.PureComponent {
|
||||
<div className={[_s.d, _s.w100PC, _s.mt5, _s.mb10].join(' ')}>
|
||||
<div className={[_s.d, _s.w100PC, _s.pt100PC].join(' ')}>
|
||||
<div className={[_s.d, _s.posAbs, _s.top0, _s.w100PC, _s.right0, _s.bottom0, _s.left0].join(' ')}>
|
||||
<div className={[_s.d, _s.w100PC, _s.h100PC, _s.aiCenter, _s.jcCenter, _s.radiusSmall, _s.bgTertiary, _s.border1PX, _s.borderColorSecondary].join(' ')}>
|
||||
<div className={[_s.d, _s.w100PC, _s.h100PC, _s.aiCenter, _s.jcCenter, _s.radiusSmall, _s.overflowHidden, _s.bgTertiary, _s.border1PX, _s.borderColorSecondary].join(' ')}>
|
||||
{ isAddable && <Icon id='add' size='20px' /> }
|
||||
{
|
||||
albumImageUrl &&
|
||||
<Image
|
||||
height='100%'
|
||||
width='100%'
|
||||
className={_s.z3}
|
||||
src={albumImageUrl}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -58,14 +71,19 @@ class Album extends React.PureComponent {
|
||||
}
|
||||
|
||||
Album.propTypes = {
|
||||
account: ImmutablePropTypes.map,
|
||||
album: ImmutablePropTypes.map,
|
||||
isAddable: PropTypes.bool,
|
||||
}
|
||||
|
||||
const mapStateToProps = (state, { albumId }) => ({
|
||||
album: state.getIn(['albums', albumId]),
|
||||
})
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
openAlbumCreate() {
|
||||
dispatch(openModal(MODAL_ALBUM_CREATE))
|
||||
}
|
||||
})
|
||||
|
||||
export default connect(null, mapDispatchToProps)(Album)
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(Album)
|
||||
@@ -23,9 +23,6 @@ class ProfileNavigationBar extends React.PureComponent {
|
||||
|
||||
render() {
|
||||
const { titleHTML } = this.props
|
||||
|
||||
// : todo :
|
||||
// fix padding on mobile device
|
||||
|
||||
return (
|
||||
<div className={[_s.d, _s.z4, _s.minH53PX, _s.w100PC].join(' ')}>
|
||||
|
||||
@@ -55,7 +55,7 @@ class MediaGalleryPanel extends ImmutablePureComponent {
|
||||
noPadding
|
||||
title={intl.formatMessage(messages.title)}
|
||||
headerButtonTitle={!!account ? intl.formatMessage(messages.show_all) : undefined}
|
||||
headerButtonTo={!!account ? `/${account.get('acct')}/albums` : undefined}
|
||||
headerButtonTo={!!account ? `/${account.get('acct')}/photos` : undefined}
|
||||
>
|
||||
<div className={[_s.d, _s.flexRow, _s.flexWrap, _s.aiCenter, _s.jcCenter].join(' ')}>
|
||||
{
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
import {
|
||||
muteAccount,
|
||||
unmuteAccount,
|
||||
} from '../../actions/interactions';
|
||||
} from '../../actions/accounts';
|
||||
import {
|
||||
deleteStatus,
|
||||
editStatus,
|
||||
@@ -197,11 +197,12 @@ class StatusOptionsPopover extends ImmutablePureComponent {
|
||||
})
|
||||
|
||||
if (status.get('bookmarked')) {
|
||||
menu.push({
|
||||
icon: 'bookmark',
|
||||
title: 'Update bookmark collection',
|
||||
onClick: this.handleBookmarkChangeClick,
|
||||
})
|
||||
// : todo :
|
||||
// menu.push({
|
||||
// icon: 'bookmark',
|
||||
// title: 'Update bookmark collection',
|
||||
// onClick: this.handleBookmarkChangeClick,
|
||||
// })
|
||||
}
|
||||
|
||||
if (status.getIn(['account', 'id']) === me) {
|
||||
|
||||
@@ -121,7 +121,7 @@ class ProfileHeader extends ImmutablePureComponent {
|
||||
title: intl.formatMessage(messages.comments),
|
||||
},
|
||||
{
|
||||
to: `/${account.get('acct')}/albums`,
|
||||
to: `/${account.get('acct')}/photos`,
|
||||
title: intl.formatMessage(messages.photos),
|
||||
},
|
||||
{
|
||||
@@ -137,7 +137,7 @@ class ProfileHeader extends ImmutablePureComponent {
|
||||
title: 'Likes',
|
||||
})
|
||||
tabs.push({
|
||||
to: `/${account.get('acct')}/bookmark_collections`,
|
||||
to: `/${account.get('acct')}/bookmarks`,
|
||||
title: intl.formatMessage(messages.bookmarks),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ class StatusCheckBox extends ImmutablePureComponent {
|
||||
preview={video.get('preview_url')}
|
||||
blurhash={video.get('blurhash')}
|
||||
src={video.get('url')}
|
||||
sourceMp4={video.get('source_mp4')}
|
||||
alt={video.get('description')}
|
||||
aspectRatio={video.getIn(['meta', 'small', 'aspect'])}
|
||||
fileContentType={video.get('file_content_type')}
|
||||
|
||||
@@ -65,6 +65,7 @@ class StatusMedia extends ImmutablePureComponent {
|
||||
preview={video.get('preview_url')}
|
||||
blurhash={video.get('blurhash')}
|
||||
src={video.get('url')}
|
||||
sourceMp4={video.get('source_mp4')}
|
||||
alt={video.get('description')}
|
||||
aspectRatio={video.getIn(['meta', 'small', 'aspect'])}
|
||||
fileContentType={video.get('file_content_type')}
|
||||
|
||||
@@ -31,10 +31,16 @@ class Video extends ImmutablePureComponent {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
videoJsOptions.sources = [{
|
||||
src: this.props.src,
|
||||
type: this.props.fileContentType,
|
||||
}]
|
||||
videoJsOptions.sources = [
|
||||
{
|
||||
src: this.props.src,
|
||||
type: this.props.fileContentType,
|
||||
},
|
||||
{
|
||||
src: this.props.sourceMp4,
|
||||
type: 'video/mp4',
|
||||
},
|
||||
]
|
||||
this.videoPlayer = videojs(this.video, videoJsOptions)
|
||||
}
|
||||
|
||||
@@ -182,6 +188,7 @@ const messages = defineMessages({
|
||||
Video.propTypes = {
|
||||
preview: PropTypes.string,
|
||||
src: PropTypes.string.isRequired,
|
||||
sourceMp4: PropTypes.string,
|
||||
alt: PropTypes.string,
|
||||
width: PropTypes.number,
|
||||
height: PropTypes.number,
|
||||
|
||||
@@ -5,8 +5,8 @@ import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import { me } from '../initial_state'
|
||||
import {
|
||||
fetchAccountAlbums,
|
||||
expandAccountAlbums,
|
||||
fetchAlbums,
|
||||
expandAlbums,
|
||||
} from '../actions/albums'
|
||||
import ColumnIndicator from '../components/column_indicator'
|
||||
import Heading from '../components/heading'
|
||||
@@ -48,7 +48,7 @@ class AccountAlbums extends ImmutablePureComponent {
|
||||
render() {
|
||||
const {
|
||||
isMe,
|
||||
albums,
|
||||
albumIds,
|
||||
account,
|
||||
accountId,
|
||||
hasMore,
|
||||
@@ -56,7 +56,9 @@ class AccountAlbums extends ImmutablePureComponent {
|
||||
} = this.props
|
||||
|
||||
if (!account) return null
|
||||
const hasAlbums = !!albums ? albums.size > 0 : false
|
||||
const hasAlbums = !!albumIds ? albumIds.size > 0 : false
|
||||
|
||||
console.log("albumIds:", albumIds)
|
||||
|
||||
return (
|
||||
<Block>
|
||||
@@ -69,11 +71,11 @@ class AccountAlbums extends ImmutablePureComponent {
|
||||
title: 'All Photos',
|
||||
to: `/${account.get('username')}/photos`,
|
||||
},
|
||||
{
|
||||
title: 'Albums',
|
||||
isActive: true,
|
||||
to: `/${account.get('username')}/albums`,
|
||||
},
|
||||
// {
|
||||
// title: 'Albums',
|
||||
// isActive: true,
|
||||
// to: `/${account.get('username')}/albums`,
|
||||
// },
|
||||
]}/>
|
||||
</div>
|
||||
|
||||
@@ -82,10 +84,10 @@ class AccountAlbums extends ImmutablePureComponent {
|
||||
|
||||
{
|
||||
hasAlbums &&
|
||||
albums.map((albums, i) => (
|
||||
albumIds.map((albumId, i) => (
|
||||
<Album
|
||||
key={album.get('id')}
|
||||
album={album}
|
||||
key={albumId}
|
||||
albumId={albumId}
|
||||
account={account}
|
||||
/>
|
||||
))
|
||||
@@ -119,7 +121,7 @@ const mapStateToProps = (state, { account, mediaType }) => {
|
||||
|
||||
return {
|
||||
accountId,
|
||||
albums: state.getIn(['album_lists', accountId, 'items']),
|
||||
albumIds: state.getIn(['album_lists', accountId, 'items']),
|
||||
isLoading: state.getIn(['album_lists', accountId, 'isLoading'], false),
|
||||
hasMore: state.getIn(['album_lists', accountId, 'hasMore'], false),
|
||||
}
|
||||
@@ -127,17 +129,17 @@ const mapStateToProps = (state, { account, mediaType }) => {
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
onFetchAccountAlbums(accountId) {
|
||||
|
||||
dispatch(fetchAlbums(accountId))
|
||||
},
|
||||
onExpandAccountAlbums(accountId) {
|
||||
|
||||
dispatch(expandAlbums(accountId))
|
||||
},
|
||||
})
|
||||
|
||||
AccountAlbums.propTypes = {
|
||||
account: ImmutablePropTypes.map,
|
||||
accountId: PropTypes.string,
|
||||
albums: ImmutablePropTypes.list,
|
||||
albumIds: ImmutablePropTypes.list,
|
||||
isLoading: PropTypes.bool,
|
||||
hasMore: PropTypes.bool,
|
||||
intl: PropTypes.object.isRequired,
|
||||
|
||||
@@ -74,7 +74,6 @@ class AccountPhotoGallery extends ImmutablePureComponent {
|
||||
|
||||
if (!account) return null
|
||||
const hasAttachments = !!attachments ? attachments.size > 0 : false
|
||||
console.log("account, isLoading, attachments:", account, isLoading, attachments, hasAttachments)
|
||||
|
||||
return (
|
||||
<Block>
|
||||
@@ -87,11 +86,11 @@ class AccountPhotoGallery extends ImmutablePureComponent {
|
||||
title: 'All Photos',
|
||||
to: `/${account.get('username')}/photos`,
|
||||
},
|
||||
{
|
||||
title: 'Albums',
|
||||
isActive: true,
|
||||
to: `/${account.get('username')}/albums`,
|
||||
},
|
||||
// {
|
||||
// title: 'Albums',
|
||||
// isActive: true,
|
||||
// to: `/${account.get('username')}/albums`,
|
||||
// },
|
||||
]}/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -8,35 +8,60 @@ import Button from '../components/button'
|
||||
import Input from '../components/input'
|
||||
import Form from '../components/form'
|
||||
import Text from '../components/text'
|
||||
import Divider from '../components/divider'
|
||||
import Textarea from '../components/textarea'
|
||||
|
||||
class AlbumCreate extends React.PureComponent {
|
||||
|
||||
state = {
|
||||
value: '',
|
||||
titleValue: '',
|
||||
descriptionValue: '',
|
||||
checked: false,
|
||||
}
|
||||
|
||||
onChange = (value) => {
|
||||
this.setState({ value })
|
||||
onChangeTitle = (titleValue) => {
|
||||
this.setState({ titleValue })
|
||||
}
|
||||
|
||||
onChangeDescription = (descriptionValue) => {
|
||||
this.setState({ descriptionValue })
|
||||
}
|
||||
|
||||
handleOnSubmit = () => {
|
||||
this.props.onSubmit(this.state.value)
|
||||
const { titleValue, descriptionValue, checked } = this.state
|
||||
this.props.onSubmit(titleValue, descriptionValue, checked)
|
||||
}
|
||||
|
||||
onTogglePrivacy = (checked) => {
|
||||
this.setState({ checked })
|
||||
}
|
||||
|
||||
render() {
|
||||
const { value } = this.state
|
||||
const {
|
||||
titleValue,
|
||||
descriptionValue,
|
||||
} = this.state
|
||||
|
||||
const isDisabled = !value
|
||||
const isDisabled = !titleValue
|
||||
|
||||
console.log("HELLO")
|
||||
|
||||
return (
|
||||
<Form>
|
||||
<Input
|
||||
title='Title'
|
||||
placeholder='Album title'
|
||||
value={value}
|
||||
onChange={this.onChange}
|
||||
value={titleValue}
|
||||
onChange={this.onChangeTitle}
|
||||
/>
|
||||
|
||||
<Divider isInvisible />
|
||||
<Textarea
|
||||
title='Description'
|
||||
placeholder='Album description'
|
||||
value={descriptionValue}
|
||||
onChange={this.onChangeDescription}
|
||||
/>
|
||||
<Divider isInvisible />
|
||||
<Button
|
||||
isDisabled={isDisabled}
|
||||
onClick={this.handleOnSubmit}
|
||||
@@ -53,9 +78,9 @@ class AlbumCreate extends React.PureComponent {
|
||||
}
|
||||
|
||||
const mapDispatchToProps = (dispatch, { isModal }) => ({
|
||||
onSubmit(title) {
|
||||
onSubmit(title, description, isPrivate) {
|
||||
if (isModal) dispatch(closeModal())
|
||||
dispatch(createBookmarkCollection(title))
|
||||
dispatch(createAlbum(title, description, isPrivate))
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ class ChatMessagesComposeForm extends React.PureComponent {
|
||||
handleOnSendChatMessage = () => {
|
||||
this.props.onSendChatMessage(this.state.value, this.props.chatConversationId)
|
||||
// document.querySelector('#gabsocial').focus()
|
||||
// this.onBlur()
|
||||
this.onFocus()
|
||||
this.setState({ value: '' })
|
||||
}
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ import DeckPage from '../../pages/deck_page'
|
||||
import {
|
||||
About,
|
||||
AccountAlbums,
|
||||
AccountAlbumGallery,
|
||||
AccountPhotoGallery,
|
||||
AccountVideoGallery,
|
||||
AccountTimeline,
|
||||
@@ -279,18 +280,18 @@ class SwitchingArea extends React.PureComponent {
|
||||
<WrappedRoute path='/:username/following' page={ProfilePage} component={Following} content={children} />
|
||||
|
||||
<WrappedRoute path='/:username/photos' exact page={ProfilePage} component={AccountPhotoGallery} content={children} componentParams={{ noSidebar: true }} />
|
||||
{ /* <WrappedRoute path='/:username/albums/:albumId' page={ProfilePage} component={AccountGallery} content={children} componentParams={{ noSidebar: true }} /> */ }
|
||||
{ /* <WrappedRoute path='/:username/albums/:albumId' page={ProfilePage} component={AccountAlbumGallery} content={children} componentParams={{ noSidebar: true }} /> */ }
|
||||
<WrappedRoute path='/:username/videos' exact page={ProfilePage} component={AccountVideoGallery} content={children} componentParams={{ noSidebar: true }} />
|
||||
<WrappedRoute path='/:username/albums' exact page={ProfilePage} component={AccountAlbums} content={children} componentParams={{ noSidebar: true }} />
|
||||
|
||||
{ /* <WrappedRoute path='/:username/albums' exact page={ProfilePage} component={AccountAlbums} content={children} componentParams={{ noSidebar: true }} /> */ }
|
||||
{ /* <WrappedRoute path='/:username/albums/create' exact page={ModalPage} component={AlbumCreate} content={children} componentParams={{ title: 'Create Album', page: 'create-album' }} /> */ }
|
||||
{ /* <WrappedRoute path='/:username/albums/:albumId/edit' page={ModalPage} component={AlbumCreate} content={children} componentParams={{ title: 'Edit Album', page: 'edit-album' }} /> */ }
|
||||
|
||||
<WrappedRoute path='/:username/likes' page={ProfilePage} component={LikedStatuses} content={children} />
|
||||
<WrappedRoute path='/:username/bookmark_collections/create' page={ModalPage} component={BookmarkCollectionCreate} content={children} componentParams={{ title: 'Create Bookmark Collection', page: 'create-bookmark-collection' }} />
|
||||
<WrappedRoute path='/:username/bookmarks' page={ProfilePage} component={BookmarkedStatuses} content={children} />
|
||||
{/*<WrappedRoute path='/:username/bookmark_collections/create' page={ModalPage} component={BookmarkCollectionCreate} content={children} componentParams={{ title: 'Create Bookmark Collection', page: 'create-bookmark-collection' }} />
|
||||
<WrappedRoute path='/:username/bookmark_collections/:bookmarkCollectionId' page={ProfilePage} component={BookmarkedStatuses} content={children} />
|
||||
<WrappedRoute path='/:username/bookmark_collections/:bookmarkCollectionId/edit' page={ModalPage} component={BookmarkCollectionCreate} content={children} componentParams={{ title: 'Edit Bookmark Collection', page: 'edit-bookmark-collection' }} />
|
||||
<WrappedRoute path='/:username/bookmark_collections' page={ProfilePage} component={BookmarkCollections} content={children} />
|
||||
<WrappedRoute path='/:username/bookmark_collections' page={ProfilePage} component={BookmarkCollections} content={children} />*/}
|
||||
|
||||
<WrappedRoute path='/:username/posts/:statusId' publicRoute exact page={BasicPage} component={StatusFeature} content={children} componentParams={{ title: 'Status', page: 'status' }} />
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ export default function album_lists(state = initialState, action) {
|
||||
case ALBUMS_EXPAND_REQUEST:
|
||||
return state.setIn([action.accountId, 'isLoading'], true)
|
||||
case ALBUMS_FETCH_SUCCESS:
|
||||
console.log("ALBUMS_FETCH_SUCCESS:", action)
|
||||
return normalizeList(state, action.accountId, action.albums, action.next)
|
||||
case ALBUMS_EXPAND_SUCCESS:
|
||||
return appendToList(state, action.accountId, action.albums, action.next)
|
||||
|
||||
@@ -2,45 +2,26 @@ import {
|
||||
ALBUMS_FETCH_REQUEST,
|
||||
ALBUMS_FETCH_SUCCESS,
|
||||
ALBUMS_FETCH_FAIL,
|
||||
ALBUMS_CREATE_SUCCESS,
|
||||
ALBUMS_REMOVE_REQUEST,
|
||||
ALBUM_CREATE_SUCCESS,
|
||||
ALBUM_REMOVE_REQUEST,
|
||||
} from '../actions/albums'
|
||||
import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable'
|
||||
|
||||
const initialState = ImmutableMap({
|
||||
items: ImmutableList(),
|
||||
isLoading: false,
|
||||
isFetched: false,
|
||||
isError: false,
|
||||
})
|
||||
const importAlbum = (state, album) => state.set(album.id, fromJS(album))
|
||||
|
||||
const importAlbums = (state, albums) =>
|
||||
state.withMutations((mutable) => albums.forEach((album) => importAlbum(mutable, album)))
|
||||
|
||||
const initialState = ImmutableMap()
|
||||
|
||||
export default function albums(state = initialState, action) {
|
||||
switch(action.type) {
|
||||
case ALBUMS_FETCH_REQUEST:
|
||||
return state.withMutations((map) => {
|
||||
map.set('isLoading', true)
|
||||
map.set('isFetched', false)
|
||||
map.set('isError', false)
|
||||
})
|
||||
case ALBUMS_FETCH_SUCCESS:
|
||||
return state.withMutations((map) => {
|
||||
map.set('items', fromJS(action.albums))
|
||||
map.set('isLoading', false)
|
||||
map.set('isFetched', true)
|
||||
map.set('isError', false)
|
||||
})
|
||||
case ALBUMS_FETCH_FAIL:
|
||||
return state.withMutations((map) => {
|
||||
map.set('isLoading', false)
|
||||
map.set('isFetched', true)
|
||||
map.set('isError', true)
|
||||
})
|
||||
case ALBUMS_CREATE_SUCCESS:
|
||||
return state.update('items', list => list.push(fromJS(action.albums)))
|
||||
case ALBUMS_REMOVE_REQUEST:
|
||||
return state.update('items', list => list.filterNot((item) => {
|
||||
return item.get('id') === action.albumId
|
||||
}))
|
||||
return importAlbums(state, action.albums)
|
||||
case ALBUM_CREATE_SUCCESS:
|
||||
return importAlbum(state, action.album)
|
||||
case ALBUM_REMOVE_REQUEST:
|
||||
return state.delete(action.albumId)
|
||||
default:
|
||||
return state
|
||||
}
|
||||
|
||||
@@ -57,8 +57,8 @@ import user_lists from './user_lists'
|
||||
const reducers = {
|
||||
accounts,
|
||||
accounts_counters,
|
||||
// albums,
|
||||
// album_lists,
|
||||
albums,
|
||||
album_lists,
|
||||
bookmark_collections,
|
||||
chats,
|
||||
chat_conversation_lists,
|
||||
|
||||
Reference in New Issue
Block a user