Rework modals to support multiple active
parent
b4f2a6979a
commit
154c34e915
|
@ -1,6 +1,5 @@
|
||||||
/// <reference lib="dom" />
|
/// <reference lib="dom" />
|
||||||
|
|
||||||
import {CropImageModal} from 'state/models/shell-ui'
|
|
||||||
import {PickerOpts, CameraOpts, CropperOpts, PickedMedia} from './types'
|
import {PickerOpts, CameraOpts, CropperOpts, PickedMedia} from './types'
|
||||||
export type {PickedMedia} from './types'
|
export type {PickedMedia} from './types'
|
||||||
import {RootStoreModel} from 'state/index'
|
import {RootStoreModel} from 'state/index'
|
||||||
|
@ -51,15 +50,17 @@ export async function openCropper(
|
||||||
): Promise<PickedMedia> {
|
): Promise<PickedMedia> {
|
||||||
// TODO handle more opts
|
// TODO handle more opts
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
store.shell.openModal(
|
store.shell.openModal({
|
||||||
new CropImageModal(opts.path, (img?: PickedMedia) => {
|
name: 'crop-image',
|
||||||
|
uri: opts.path,
|
||||||
|
onSelect: (img?: PickedMedia) => {
|
||||||
if (img) {
|
if (img) {
|
||||||
resolve(img)
|
resolve(img)
|
||||||
} else {
|
} else {
|
||||||
reject(new Error('Canceled'))
|
reject(new Error('Canceled'))
|
||||||
}
|
}
|
||||||
}),
|
},
|
||||||
)
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,75 +2,57 @@ import {RootStoreModel} from './root-store'
|
||||||
import {makeAutoObservable} from 'mobx'
|
import {makeAutoObservable} from 'mobx'
|
||||||
import {ProfileViewModel} from './profile-view'
|
import {ProfileViewModel} from './profile-view'
|
||||||
import {isObj, hasProp} from 'lib/type-guards'
|
import {isObj, hasProp} from 'lib/type-guards'
|
||||||
import {PickedMedia} from 'view/com/util/images/image-crop-picker/types'
|
import {PickedMedia} from 'lib/media/types'
|
||||||
|
|
||||||
export class ConfirmModal {
|
export interface ConfirmModal {
|
||||||
name = 'confirm'
|
name: 'confirm'
|
||||||
|
title: string
|
||||||
constructor(
|
message: string | (() => JSX.Element)
|
||||||
public title: string,
|
onPressConfirm: () => void | Promise<void>
|
||||||
public message: string | (() => JSX.Element),
|
|
||||||
public onPressConfirm: () => void | Promise<void>,
|
|
||||||
) {
|
|
||||||
makeAutoObservable(this)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class EditProfileModal {
|
export interface EditProfileModal {
|
||||||
name = 'edit-profile'
|
name: 'edit-profile'
|
||||||
|
profileView: ProfileViewModel
|
||||||
constructor(
|
onUpdate?: () => void
|
||||||
public profileView: ProfileViewModel,
|
|
||||||
public onUpdate?: () => void,
|
|
||||||
) {
|
|
||||||
makeAutoObservable(this)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ServerInputModal {
|
export interface ServerInputModal {
|
||||||
name = 'server-input'
|
name: 'server-input'
|
||||||
|
initialService: string
|
||||||
constructor(
|
onSelect: (url: string) => void
|
||||||
public initialService: string,
|
|
||||||
public onSelect: (url: string) => void,
|
|
||||||
) {
|
|
||||||
makeAutoObservable(this)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ReportPostModal {
|
export interface ReportPostModal {
|
||||||
name = 'report-post'
|
name: 'report-post'
|
||||||
|
postUri: string
|
||||||
constructor(public postUri: string, public postCid: string) {
|
postCid: string
|
||||||
makeAutoObservable(this)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ReportAccountModal {
|
export interface ReportAccountModal {
|
||||||
name = 'report-account'
|
name: 'report-account'
|
||||||
|
did: string
|
||||||
constructor(public did: string) {
|
|
||||||
makeAutoObservable(this)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CropImageModal {
|
export interface CropImageModal {
|
||||||
name = 'crop-image'
|
name: 'crop-image'
|
||||||
|
uri: string
|
||||||
constructor(
|
onSelect: (img?: PickedMedia) => void
|
||||||
public uri: string,
|
|
||||||
public onSelect: (img?: PickedMedia) => void,
|
|
||||||
) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DeleteAccountModal {
|
export interface DeleteAccountModal {
|
||||||
name = 'delete-account'
|
name: 'delete-account'
|
||||||
|
|
||||||
constructor() {
|
|
||||||
makeAutoObservable(this)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type Modal =
|
||||||
|
| ConfirmModal
|
||||||
|
| EditProfileModal
|
||||||
|
| ServerInputModal
|
||||||
|
| ReportPostModal
|
||||||
|
| ReportAccountModal
|
||||||
|
| CropImageModal
|
||||||
|
| DeleteAccountModal
|
||||||
|
|
||||||
interface LightboxModel {}
|
interface LightboxModel {}
|
||||||
|
|
||||||
export class ProfileImageLightbox implements LightboxModel {
|
export class ProfileImageLightbox implements LightboxModel {
|
||||||
|
@ -111,15 +93,7 @@ export class ShellUiModel {
|
||||||
minimalShellMode = false
|
minimalShellMode = false
|
||||||
isMainMenuOpen = false
|
isMainMenuOpen = false
|
||||||
isModalActive = false
|
isModalActive = false
|
||||||
activeModal:
|
activeModals: Modal[] = []
|
||||||
| ConfirmModal
|
|
||||||
| EditProfileModal
|
|
||||||
| ServerInputModal
|
|
||||||
| ReportPostModal
|
|
||||||
| ReportAccountModal
|
|
||||||
| CropImageModal
|
|
||||||
| DeleteAccountModal
|
|
||||||
| undefined
|
|
||||||
isLightboxActive = false
|
isLightboxActive = false
|
||||||
activeLightbox: ProfileImageLightbox | ImagesLightbox | undefined
|
activeLightbox: ProfileImageLightbox | ImagesLightbox | undefined
|
||||||
isComposerActive = false
|
isComposerActive = false
|
||||||
|
@ -159,24 +133,15 @@ export class ShellUiModel {
|
||||||
this.isMainMenuOpen = v
|
this.isMainMenuOpen = v
|
||||||
}
|
}
|
||||||
|
|
||||||
openModal(
|
openModal(modal: Modal) {
|
||||||
modal:
|
|
||||||
| ConfirmModal
|
|
||||||
| EditProfileModal
|
|
||||||
| ServerInputModal
|
|
||||||
| ReportPostModal
|
|
||||||
| ReportAccountModal
|
|
||||||
| CropImageModal
|
|
||||||
| DeleteAccountModal,
|
|
||||||
) {
|
|
||||||
this.rootStore.emitNavigation()
|
this.rootStore.emitNavigation()
|
||||||
this.isModalActive = true
|
this.isModalActive = true
|
||||||
this.activeModal = modal
|
this.activeModals.push(modal)
|
||||||
}
|
}
|
||||||
|
|
||||||
closeModal() {
|
closeModal() {
|
||||||
this.isModalActive = false
|
this.activeModals.pop()
|
||||||
this.activeModal = undefined
|
this.isModalActive = this.activeModals.length > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
openLightbox(lightbox: ProfileImageLightbox | ImagesLightbox) {
|
openLightbox(lightbox: ProfileImageLightbox | ImagesLightbox) {
|
||||||
|
|
|
@ -17,7 +17,7 @@ import {
|
||||||
VirtualizedList,
|
VirtualizedList,
|
||||||
ModalProps,
|
ModalProps,
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
import {Modal} from '../../modals/Modal'
|
import {ModalsContainer} from '../../modals/Modal'
|
||||||
|
|
||||||
import ImageItem from './components/ImageItem/ImageItem'
|
import ImageItem from './components/ImageItem/ImageItem'
|
||||||
import ImageDefaultHeader from './components/ImageDefaultHeader'
|
import ImageDefaultHeader from './components/ImageDefaultHeader'
|
||||||
|
@ -98,7 +98,7 @@ function ImageViewing({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.screen} onLayout={onLayout}>
|
<View style={styles.screen} onLayout={onLayout}>
|
||||||
<Modal />
|
<ModalsContainer />
|
||||||
<View style={[styles.container, {opacity, backgroundColor}]}>
|
<View style={[styles.container, {opacity, backgroundColor}]}>
|
||||||
<Animated.View style={[styles.header, {transform: headerTransform}]}>
|
<Animated.View style={[styles.header, {transform: headerTransform}]}>
|
||||||
{typeof HeaderComponent !== 'undefined' ? (
|
{typeof HeaderComponent !== 'undefined' ? (
|
||||||
|
|
|
@ -25,7 +25,6 @@ import {makeValidHandle, createFullHandle} from 'lib/strings/handles'
|
||||||
import {toNiceDomain} from 'lib/strings/url-helpers'
|
import {toNiceDomain} from 'lib/strings/url-helpers'
|
||||||
import {useStores, DEFAULT_SERVICE} from 'state/index'
|
import {useStores, DEFAULT_SERVICE} from 'state/index'
|
||||||
import {ServiceDescription} from 'state/models/session'
|
import {ServiceDescription} from 'state/models/session'
|
||||||
import {ServerInputModal} from 'state/models/shell-ui'
|
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
import {cleanError} from 'lib/strings/errors'
|
import {cleanError} from 'lib/strings/errors'
|
||||||
|
|
||||||
|
@ -84,7 +83,11 @@ export const CreateAccount = ({onPressBack}: {onPressBack: () => void}) => {
|
||||||
const onPressRetryConnect = () => setRetryDescribeTrigger({})
|
const onPressRetryConnect = () => setRetryDescribeTrigger({})
|
||||||
|
|
||||||
const onPressSelectService = () => {
|
const onPressSelectService = () => {
|
||||||
store.shell.openModal(new ServerInputModal(serviceUrl, setServiceUrl))
|
store.shell.openModal({
|
||||||
|
name: 'server-input',
|
||||||
|
initialService: serviceUrl,
|
||||||
|
onSelect: setServiceUrl,
|
||||||
|
})
|
||||||
Keyboard.dismiss()
|
Keyboard.dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -279,7 +279,11 @@ const LoginForm = ({
|
||||||
const [password, setPassword] = useState<string>('')
|
const [password, setPassword] = useState<string>('')
|
||||||
|
|
||||||
const onPressSelectService = () => {
|
const onPressSelectService = () => {
|
||||||
store.shell.openModal(new ServerInputModal(serviceUrl, setServiceUrl))
|
store.shell.openModal({
|
||||||
|
name: 'server-input',
|
||||||
|
initialService: serviceUrl,
|
||||||
|
onSelect: setServiceUrl,
|
||||||
|
})
|
||||||
Keyboard.dismiss()
|
Keyboard.dismiss()
|
||||||
track('Signin:PressedSelectService')
|
track('Signin:PressedSelectService')
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,6 @@ import BottomSheet from '@gorhom/bottom-sheet'
|
||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
import {createCustomBackdrop} from '../util/BottomSheetCustomBackdrop'
|
import {createCustomBackdrop} from '../util/BottomSheetCustomBackdrop'
|
||||||
|
|
||||||
import * as models from 'state/models/shell-ui'
|
|
||||||
|
|
||||||
import * as ConfirmModal from './Confirm'
|
import * as ConfirmModal from './Confirm'
|
||||||
import * as EditProfileModal from './EditProfile'
|
import * as EditProfileModal from './EditProfile'
|
||||||
import * as ServerInputModal from './ServerInput'
|
import * as ServerInputModal from './ServerInput'
|
||||||
|
@ -32,52 +30,37 @@ export const Modal = observer(function Modal() {
|
||||||
store.shell.closeModal()
|
store.shell.closeModal()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const activeModal = React.useMemo(
|
||||||
|
() => store.shell.activeModals.at(-1),
|
||||||
|
[store.shell.activeModals],
|
||||||
|
)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (store.shell.isModalActive) {
|
if (store.shell.isModalActive) {
|
||||||
bottomSheetRef.current?.expand()
|
bottomSheetRef.current?.expand()
|
||||||
} else {
|
} else {
|
||||||
bottomSheetRef.current?.close()
|
bottomSheetRef.current?.close()
|
||||||
}
|
}
|
||||||
}, [store.shell.isModalActive, bottomSheetRef, store.shell.activeModal?.name])
|
}, [store.shell.isModalActive, bottomSheetRef, activeModal?.name])
|
||||||
|
|
||||||
let snapPoints: (string | number)[] = CLOSED_SNAPPOINTS
|
let snapPoints: (string | number)[] = CLOSED_SNAPPOINTS
|
||||||
let element
|
let element
|
||||||
if (store.shell.activeModal?.name === 'confirm') {
|
if (activeModal?.name === 'confirm') {
|
||||||
snapPoints = ConfirmModal.snapPoints
|
snapPoints = ConfirmModal.snapPoints
|
||||||
element = (
|
element = <ConfirmModal.Component {...activeModal} />
|
||||||
<ConfirmModal.Component
|
} else if (activeModal?.name === 'edit-profile') {
|
||||||
{...(store.shell.activeModal as models.ConfirmModal)}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
} else if (store.shell.activeModal?.name === 'edit-profile') {
|
|
||||||
snapPoints = EditProfileModal.snapPoints
|
snapPoints = EditProfileModal.snapPoints
|
||||||
element = (
|
element = <EditProfileModal.Component {...activeModal} />
|
||||||
<EditProfileModal.Component
|
} else if (activeModal?.name === 'server-input') {
|
||||||
{...(store.shell.activeModal as models.EditProfileModal)}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
} else if (store.shell.activeModal?.name === 'server-input') {
|
|
||||||
snapPoints = ServerInputModal.snapPoints
|
snapPoints = ServerInputModal.snapPoints
|
||||||
element = (
|
element = <ServerInputModal.Component {...activeModal} />
|
||||||
<ServerInputModal.Component
|
} else if (activeModal?.name === 'report-post') {
|
||||||
{...(store.shell.activeModal as models.ServerInputModal)}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
} else if (store.shell.activeModal?.name === 'report-post') {
|
|
||||||
snapPoints = ReportPostModal.snapPoints
|
snapPoints = ReportPostModal.snapPoints
|
||||||
element = (
|
element = <ReportPostModal.Component {...activeModal} />
|
||||||
<ReportPostModal.Component
|
} else if (activeModal?.name === 'report-account') {
|
||||||
{...(store.shell.activeModal as models.ReportPostModal)}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
} else if (store.shell.activeModal?.name === 'report-account') {
|
|
||||||
snapPoints = ReportAccountModal.snapPoints
|
snapPoints = ReportAccountModal.snapPoints
|
||||||
element = (
|
element = <ReportAccountModal.Component {...activeModal} />
|
||||||
<ReportAccountModal.Component
|
} else if (activeModal?.name === 'delete-account') {
|
||||||
{...(store.shell.activeModal as models.ReportAccountModal)}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
} else if (store.shell.activeModal?.name === 'delete-account') {
|
|
||||||
snapPoints = DeleteAccountModal.snapPoints
|
snapPoints = DeleteAccountModal.snapPoints
|
||||||
element = <DeleteAccountModal.Component />
|
element = <DeleteAccountModal.Component />
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -3,8 +3,7 @@ import {TouchableWithoutFeedback, StyleSheet, View} from 'react-native'
|
||||||
import {observer} from 'mobx-react-lite'
|
import {observer} from 'mobx-react-lite'
|
||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
|
import type {Modal as ModalIface} from 'state/models/shell-ui'
|
||||||
import * as models from 'state/models/shell-ui'
|
|
||||||
|
|
||||||
import * as ConfirmModal from './Confirm'
|
import * as ConfirmModal from './Confirm'
|
||||||
import * as EditProfileModal from './EditProfile'
|
import * as EditProfileModal from './EditProfile'
|
||||||
|
@ -13,7 +12,23 @@ import * as ReportPostModal from './ReportPost'
|
||||||
import * as ReportAccountModal from './ReportAccount'
|
import * as ReportAccountModal from './ReportAccount'
|
||||||
import * as CropImageModal from './crop-image/CropImage.web'
|
import * as CropImageModal from './crop-image/CropImage.web'
|
||||||
|
|
||||||
export const Modal = observer(function Modal() {
|
export const ModalsContainer = observer(function ModalsContainer() {
|
||||||
|
const store = useStores()
|
||||||
|
|
||||||
|
if (!store.shell.isModalActive) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{store.shell.activeModals.map((modal, i) => (
|
||||||
|
<Modal key={`modal-${i}`} modal={modal} />
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
function Modal({modal}: {modal: ModalIface}) {
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
|
|
||||||
|
@ -22,7 +37,7 @@ export const Modal = observer(function Modal() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const onPressMask = () => {
|
const onPressMask = () => {
|
||||||
if (store.shell.activeModal?.name === 'crop-image') {
|
if (modal.name === 'crop-image') {
|
||||||
return // dont close on mask presses during crop
|
return // dont close on mask presses during crop
|
||||||
}
|
}
|
||||||
store.shell.closeModal()
|
store.shell.closeModal()
|
||||||
|
@ -32,42 +47,18 @@ export const Modal = observer(function Modal() {
|
||||||
}
|
}
|
||||||
|
|
||||||
let element
|
let element
|
||||||
if (store.shell.activeModal?.name === 'confirm') {
|
if (modal.name === 'confirm') {
|
||||||
element = (
|
element = <ConfirmModal.Component {...modal} />
|
||||||
<ConfirmModal.Component
|
} else if (modal.name === 'edit-profile') {
|
||||||
{...(store.shell.activeModal as models.ConfirmModal)}
|
element = <EditProfileModal.Component {...modal} />
|
||||||
/>
|
} else if (modal.name === 'server-input') {
|
||||||
)
|
element = <ServerInputModal.Component {...modal} />
|
||||||
} else if (store.shell.activeModal?.name === 'edit-profile') {
|
} else if (modal.name === 'report-post') {
|
||||||
element = (
|
element = <ReportPostModal.Component {...modal} />
|
||||||
<EditProfileModal.Component
|
} else if (modal.name === 'report-account') {
|
||||||
{...(store.shell.activeModal as models.EditProfileModal)}
|
element = <ReportAccountModal.Component {...modal} />
|
||||||
/>
|
} else if (modal.name === 'crop-image') {
|
||||||
)
|
element = <CropImageModal.Component {...modal} />
|
||||||
} else if (store.shell.activeModal?.name === 'server-input') {
|
|
||||||
element = (
|
|
||||||
<ServerInputModal.Component
|
|
||||||
{...(store.shell.activeModal as models.ServerInputModal)}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
} else if (store.shell.activeModal?.name === 'report-post') {
|
|
||||||
element = (
|
|
||||||
<ReportPostModal.Component
|
|
||||||
{...(store.shell.activeModal as models.ReportPostModal)}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
} else if (store.shell.activeModal?.name === 'report-account') {
|
|
||||||
element = (
|
|
||||||
<ReportAccountModal.Component
|
|
||||||
{...(store.shell.activeModal as models.ReportAccountModal)}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
} else if (store.shell.activeModal?.name === 'crop-image') {
|
|
||||||
element = (
|
|
||||||
<CropImageModal.Component
|
|
||||||
{...(store.shell.activeModal as models.CropImageModal)}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -81,7 +72,7 @@ export const Modal = observer(function Modal() {
|
||||||
</View>
|
</View>
|
||||||
</TouchableWithoutFeedback>
|
</TouchableWithoutFeedback>
|
||||||
)
|
)
|
||||||
})
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
mask: {
|
mask: {
|
||||||
|
|
|
@ -15,11 +15,7 @@ import {
|
||||||
import {BlurView} from '../util/BlurView'
|
import {BlurView} from '../util/BlurView'
|
||||||
import {ProfileViewModel} from 'state/models/profile-view'
|
import {ProfileViewModel} from 'state/models/profile-view'
|
||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
import {
|
import {ProfileImageLightbox} from 'state/models/shell-ui'
|
||||||
EditProfileModal,
|
|
||||||
ReportAccountModal,
|
|
||||||
ProfileImageLightbox,
|
|
||||||
} from 'state/models/shell-ui'
|
|
||||||
import {pluralize} from 'lib/strings/helpers'
|
import {pluralize} from 'lib/strings/helpers'
|
||||||
import {toShareUrl} from 'lib/strings/url-helpers'
|
import {toShareUrl} from 'lib/strings/url-helpers'
|
||||||
import {s, gradients} from 'lib/styles'
|
import {s, gradients} from 'lib/styles'
|
||||||
|
@ -65,7 +61,11 @@ export const ProfileHeader = observer(function ProfileHeader({
|
||||||
}
|
}
|
||||||
const onPressEditProfile = () => {
|
const onPressEditProfile = () => {
|
||||||
track('ProfileHeader:EditProfileButtonClicked')
|
track('ProfileHeader:EditProfileButtonClicked')
|
||||||
store.shell.openModal(new EditProfileModal(view, onRefreshAll))
|
store.shell.openModal({
|
||||||
|
name: 'edit-profile',
|
||||||
|
profileView: view,
|
||||||
|
onUpdate: onRefreshAll,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
const onPressFollowers = () => {
|
const onPressFollowers = () => {
|
||||||
track('ProfileHeader:FollowersButtonClicked')
|
track('ProfileHeader:FollowersButtonClicked')
|
||||||
|
@ -101,7 +101,10 @@ export const ProfileHeader = observer(function ProfileHeader({
|
||||||
}
|
}
|
||||||
const onPressReportAccount = () => {
|
const onPressReportAccount = () => {
|
||||||
track('ProfileHeader:ReportAccountButtonClicked')
|
track('ProfileHeader:ReportAccountButtonClicked')
|
||||||
store.shell.openModal(new ReportAccountModal(view.did))
|
store.shell.openModal({
|
||||||
|
name: 'report-account',
|
||||||
|
did: view.did,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// loading
|
// loading
|
||||||
|
|
|
@ -18,6 +18,7 @@ import {useStores} from 'state/index'
|
||||||
import {colors, gradients} from 'lib/styles'
|
import {colors, gradients} from 'lib/styles'
|
||||||
import {DropdownButton} from './forms/DropdownButton'
|
import {DropdownButton} from './forms/DropdownButton'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
|
import {isWeb} from 'platform/detection'
|
||||||
|
|
||||||
export function UserAvatar({
|
export function UserAvatar({
|
||||||
size,
|
size,
|
||||||
|
@ -58,7 +59,7 @@ export function UserAvatar({
|
||||||
)
|
)
|
||||||
|
|
||||||
const dropdownItems = [
|
const dropdownItems = [
|
||||||
{
|
!isWeb && {
|
||||||
label: 'Camera',
|
label: 'Camera',
|
||||||
icon: 'camera' as IconProp,
|
icon: 'camera' as IconProp,
|
||||||
onPress: async () => {
|
onPress: async () => {
|
||||||
|
|
|
@ -18,6 +18,7 @@ import {
|
||||||
} from 'lib/permissions'
|
} from 'lib/permissions'
|
||||||
import {DropdownButton} from './forms/DropdownButton'
|
import {DropdownButton} from './forms/DropdownButton'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
|
import {isWeb} from 'platform/detection'
|
||||||
|
|
||||||
export function UserBanner({
|
export function UserBanner({
|
||||||
banner,
|
banner,
|
||||||
|
@ -29,7 +30,7 @@ export function UserBanner({
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
const dropdownItems = [
|
const dropdownItems = [
|
||||||
{
|
!isWeb && {
|
||||||
label: 'Camera',
|
label: 'Camera',
|
||||||
icon: 'camera' as IconProp,
|
icon: 'camera' as IconProp,
|
||||||
onPress: async () => {
|
onPress: async () => {
|
||||||
|
|
|
@ -16,7 +16,6 @@ import {Button, ButtonType} from './Button'
|
||||||
import {colors} from 'lib/styles'
|
import {colors} from 'lib/styles'
|
||||||
import {toShareUrl} from 'lib/strings/url-helpers'
|
import {toShareUrl} from 'lib/strings/url-helpers'
|
||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
import {ReportPostModal, ConfirmModal} from 'state/models/shell-ui'
|
|
||||||
import {TABS_ENABLED} from 'lib/build-flags'
|
import {TABS_ENABLED} from 'lib/build-flags'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
import {useTheme} from 'lib/ThemeContext'
|
import {useTheme} from 'lib/ThemeContext'
|
||||||
|
@ -28,6 +27,7 @@ export interface DropdownItem {
|
||||||
label: string
|
label: string
|
||||||
onPress: () => void
|
onPress: () => void
|
||||||
}
|
}
|
||||||
|
type MaybeDropdownItem = DropdownItem | false | undefined
|
||||||
|
|
||||||
export type DropdownButtonType = ButtonType | 'bare'
|
export type DropdownButtonType = ButtonType | 'bare'
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ export function DropdownButton({
|
||||||
}: {
|
}: {
|
||||||
type?: DropdownButtonType
|
type?: DropdownButtonType
|
||||||
style?: StyleProp<ViewStyle>
|
style?: StyleProp<ViewStyle>
|
||||||
items: DropdownItem[]
|
items: MaybeDropdownItem[]
|
||||||
label?: string
|
label?: string
|
||||||
menuWidth?: number
|
menuWidth?: number
|
||||||
children?: React.ReactNode
|
children?: React.ReactNode
|
||||||
|
@ -71,7 +71,12 @@ export function DropdownButton({
|
||||||
? pageX + width + rightOffset
|
? pageX + width + rightOffset
|
||||||
: pageX + width - menuWidth
|
: pageX + width - menuWidth
|
||||||
const newY = pageY + height + bottomOffset
|
const newY = pageY + height + bottomOffset
|
||||||
createDropdownMenu(newX, newY, menuWidth, items)
|
createDropdownMenu(
|
||||||
|
newX,
|
||||||
|
newY,
|
||||||
|
menuWidth,
|
||||||
|
items.filter(v => !!v) as DropdownItem[],
|
||||||
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -151,7 +156,11 @@ export function PostDropdownBtn({
|
||||||
icon: 'circle-exclamation',
|
icon: 'circle-exclamation',
|
||||||
label: 'Report post',
|
label: 'Report post',
|
||||||
onPress() {
|
onPress() {
|
||||||
store.shell.openModal(new ReportPostModal(itemUri, itemCid))
|
store.shell.openModal({
|
||||||
|
name: 'report-post',
|
||||||
|
postUri: itemUri,
|
||||||
|
postCid: itemCid,
|
||||||
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
isAuthor
|
isAuthor
|
||||||
|
@ -159,13 +168,12 @@ export function PostDropdownBtn({
|
||||||
icon: ['far', 'trash-can'],
|
icon: ['far', 'trash-can'],
|
||||||
label: 'Delete post',
|
label: 'Delete post',
|
||||||
onPress() {
|
onPress() {
|
||||||
store.shell.openModal(
|
store.shell.openModal({
|
||||||
new ConfirmModal(
|
name: 'confirm',
|
||||||
'Delete this post?',
|
title: 'Delete this post?',
|
||||||
'Are you sure? This can not be undone.',
|
message: 'Are you sure? This can not be undone.',
|
||||||
onDeletePost,
|
onPressConfirm: onDeletePost,
|
||||||
),
|
})
|
||||||
)
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
|
|
|
@ -28,7 +28,7 @@ import {Login} from '../../screens/Login'
|
||||||
import {Menu} from './Menu'
|
import {Menu} from './Menu'
|
||||||
import {Onboard} from '../../screens/Onboard'
|
import {Onboard} from '../../screens/Onboard'
|
||||||
import {HorzSwipe} from '../../com/util/gestures/HorzSwipe'
|
import {HorzSwipe} from '../../com/util/gestures/HorzSwipe'
|
||||||
import {Modal} from '../../com/modals/Modal'
|
import {ModalsContainer} from '../../com/modals/Modal'
|
||||||
import {Lightbox} from '../../com/lightbox/Lightbox'
|
import {Lightbox} from '../../com/lightbox/Lightbox'
|
||||||
import {Text} from '../../com/util/text/Text'
|
import {Text} from '../../com/util/text/Text'
|
||||||
import {ErrorBoundary} from '../../com/util/ErrorBoundary'
|
import {ErrorBoundary} from '../../com/util/ErrorBoundary'
|
||||||
|
@ -366,7 +366,7 @@ export const MobileShell: React.FC = observer(() => {
|
||||||
return (
|
return (
|
||||||
<View style={styles.outerContainer}>
|
<View style={styles.outerContainer}>
|
||||||
<Login />
|
<Login />
|
||||||
<Modal />
|
<ModalsContainer />
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -515,7 +515,7 @@ export const MobileShell: React.FC = observer(() => {
|
||||||
notificationCount={store.me.notifications.unreadCount}
|
notificationCount={store.me.notifications.unreadCount}
|
||||||
/>
|
/>
|
||||||
</Animated.View>
|
</Animated.View>
|
||||||
<Modal />
|
<ModalsContainer />
|
||||||
<Lightbox />
|
<Lightbox />
|
||||||
<Composer
|
<Composer
|
||||||
active={store.shell.isComposerActive}
|
active={store.shell.isComposerActive}
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {Onboard} from '../../screens/Onboard'
|
||||||
import {Login} from '../../screens/Login'
|
import {Login} from '../../screens/Login'
|
||||||
import {ErrorBoundary} from '../../com/util/ErrorBoundary'
|
import {ErrorBoundary} from '../../com/util/ErrorBoundary'
|
||||||
import {Lightbox} from '../../com/lightbox/Lightbox'
|
import {Lightbox} from '../../com/lightbox/Lightbox'
|
||||||
import {Modal} from '../../com/modals/Modal'
|
import {ModalsContainer} from '../../com/modals/Modal'
|
||||||
import {Text} from 'view/com/util/text/Text'
|
import {Text} from 'view/com/util/text/Text'
|
||||||
import {Composer} from './Composer'
|
import {Composer} from './Composer'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
|
@ -32,7 +32,7 @@ export const WebShell: React.FC = observer(() => {
|
||||||
return (
|
return (
|
||||||
<View style={styles.outerContainer}>
|
<View style={styles.outerContainer}>
|
||||||
<Login />
|
<Login />
|
||||||
<Modal />
|
<ModalsContainer />
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ export const WebShell: React.FC = observer(() => {
|
||||||
imagesOpen={store.shell.composerOpts?.imagesOpen}
|
imagesOpen={store.shell.composerOpts?.imagesOpen}
|
||||||
onPost={store.shell.composerOpts?.onPost}
|
onPost={store.shell.composerOpts?.onPost}
|
||||||
/>
|
/>
|
||||||
<Modal />
|
<ModalsContainer />
|
||||||
<Lightbox />
|
<Lightbox />
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue