import { applyMixins } from '@nativescript-community/ui-material-core' ; import { AndroidActivityBackPressedEventData , Application , Utils , View , fromObject } from '@nativescript/core' ; import { BottomSheetOptions , StateBottomSheet , ViewWithBottomSheetBase } from './bottomsheet-common' ; export { ViewWithBottomSheetBase } from './bottomsheet-common' ; interface BottomSheetDataOptions { owner : View ; options : BottomSheetOptions ; shownCallback : ( ) => void ; dismissCallback : ( ) => void ; } function getId ( id ) { const context = Application . android . context ; return context . getResources ( ) . getIdentifier ( id , 'id' , context . getPackageName ( ) ) ; } @ NativeClass class ChangeStateBottomSheet extends com . google . android . material . bottomsheet . BottomSheetBehavior . BottomSheetCallback { private owner : ViewWithBottomSheet ; constructor ( owner ) { super ( ) ; this . owner = owner ; return global . __native ( this ) ; } onSlide ( bottomSheet , slideOffset ) { if ( this . checkActiveCallback ( ) ) { this . owner . _onChangeStateBottomSheetCallback ( StateBottomSheet . DRAGGING , slideOffset ) ; } } onStateChanged ( bottomSheet , newState ) { if ( this . checkActiveCallback ( ) ) { const status = this . getStateBottomSheetFromBottomSheetBehavior ( newState ) ; if ( status !== undefined ) { this . owner . _onChangeStateBottomSheetCallback ( status ) ; } } } private checkActiveCallback ( ) { return this . owner && this . owner . _onChangeStateBottomSheetCallback ; } public getStateBottomSheetFromBottomSheetBehavior ( state ) { switch ( state ) { case com . google . android . material . bottomsheet . BottomSheetBehavior . STATE_HIDDEN : return StateBottomSheet . CLOSED ; case com . google . android . material . bottomsheet . BottomSheetBehavior . STATE_EXPANDED : return StateBottomSheet . EXPANDED ; case com . google . android . material . bottomsheet . BottomSheetBehavior . STATE_COLLAPSED : return StateBottomSheet . COLLAPSED ; case com . google . android . material . bottomsheet . BottomSheetBehavior . STATE_DRAGGING : return StateBottomSheet . DRAGGING ; default : return ; } } } export class ViewWithBottomSheet extends ViewWithBottomSheetBase { _bottomSheetFragment : com . nativescript . material . bottomsheet . BottomSheetDialogFragment ; protected _hideNativeBottomSheet ( parent , whenClosedCallback ) { whenClosedCallback ( ) ; const manager = this . _bottomSheetFragment . getFragmentManager ( ) ; if ( manager ) { this . _bottomSheetFragment . dismissAllowingStateLoss ( ) ; } this . _bottomSheetFragment = null ; } protected _showNativeBottomSheet ( parent , options ) { this . _commonShowNativeBottomSheet ( parent , options ) ; const owner = this ; const domId = this . _domId ; const bottomSheetOptions = { owner : this , options , shownCallback : ( ) => { this . bindingContext = fromObject ( options . context ) ; this . _raiseShownBottomSheetEvent ( ) ; } , dismissCallback : ( ) => this . _onDismissBottomSheetCallback ( ) } ; const dfListener = new com . nativescript . material . bottomsheet . BottomSheetDialogFragment . BottomSheetDialogFragmentListener ( { onCreateDialog ( fragment , savedInstanceState ) { const theme = fragment . getTheme ( ) ; const dialogListener = new com . nativescript . material . bottomsheet . BottomSheetDialog . BottomSheetDialogListener ( { onDetachedFromWindow ( dialog ) { ( dialog as any ) . nListener = null ; } , onBackPressed ( dialog ) { if ( bottomSheetOptions . options && bottomSheetOptions . options . dismissOnBackButton === false ) { return true ; } if ( ! owner ) { return false ; } const args = { eventName : 'activityBackPressed' , object : owner , activity : owner . _context , cancel : false } as AndroidActivityBackPressedEventData ; Application . android . notify ( args ) ; if ( args . cancel ) { return true ; } owner . notify ( args ) ; if ( ! args . cancel ) { args . cancel = owner . onBackPressed ( ) ; } return args . cancel ; } } ) ; const dialog = new com . nativescript . material . bottomsheet . BottomSheetDialog ( fragment . getActivity ( ) , theme ) ; dialog . setListener ( dialogListener ) ; ( dialog as any ) . nListener = dialogListener ; if ( bottomSheetOptions . options ) { const creationOptions = bottomSheetOptions . options ; if ( creationOptions . dismissOnBackgroundTap !== undefined ) { dialog . setCanceledOnTouchOutside ( creationOptions . dismissOnBackgroundTap ) ; } if ( creationOptions . disableDimBackground === true ) { dialog . getWindow ( ) . clearFlags ( android . view . WindowManager . LayoutParams . FLAG_DIM_BEHIND ) ; } } return dialog ; } , onCreateView ( fragment , inflater , container , savedInstanceState ) { owner . _setupAsRootView ( fragment . getActivity ( ) ) ; owner . _isAddedToNativeVisualTree = true ; return owner . nativeViewProtected ; } , onStart ( fragment ) { const color = owner . backgroundColor ; const contentViewId = getId ( 'design_bottom_sheet' ) ; const view = fragment . getDialog ( ) . findViewById ( contentViewId ) ; const transparent = bottomSheetOptions . options && bottomSheetOptions . options . transparent ; if ( transparent === true ) { setTimeout ( ( ) => { view . setBackground ( null ) ; } , 0 ) ; } const behavior = com . google . android . material . bottomsheet . BottomSheetBehavior . from ( view ) ; const dismissOnDraggingDownSheet = ! bottomSheetOptions . options || bottomSheetOptions . options . dismissOnDraggingDownSheet !== false ; behavior . setHideable ( dismissOnDraggingDownSheet ) ; if ( ! dismissOnDraggingDownSheet ) { behavior . setState ( com . google . android . material . bottomsheet . BottomSheetBehavior . STATE_EXPANDED ) ; behavior . setPeekHeight ( java . lang . Integer . MAX_VALUE ) ; } const skipCollapsedState = ! bottomSheetOptions . options || bottomSheetOptions . options . skipCollapsedState === true ; if ( skipCollapsedState ) { behavior . setState ( com . google . android . material . bottomsheet . BottomSheetBehavior . STATE_EXPANDED ) ; behavior . setSkipCollapsed ( true ) ; } const peekHeight = bottomSheetOptions . options ?. peekHeight ; if ( peekHeight ) { behavior . setState ( com . google . android . material . bottomsheet . BottomSheetBehavior . STATE_COLLAPSED ) ; behavior . setPeekHeight ( Utils . layout . toDevicePixels ( peekHeight ) ) ; } const onChangeState = bottomSheetOptions . options ?. onChangeState ; if ( onChangeState ) { const changeStateBottomSheet = new ChangeStateBottomSheet ( owner ) ; behavior . addBottomSheetCallback ( changeStateBottomSheet ) ; owner . _onChangeStateBottomSheetCallback ( changeStateBottomSheet . getStateBottomSheetFromBottomSheetBehavior ( behavior . getState ( ) ) ) ; } if ( owner && ! owner . isLoaded ) { owner . callLoaded ( ) ; } bottomSheetOptions . shownCallback ( ) ; } , onDismiss ( fragment , dialog ) { const manager = fragment . getFragmentManager ( ) ; if ( manager ) { bottomSheetOptions . dismissCallback ( ) ; } if ( owner && owner . isLoaded ) { owner . callUnloaded ( ) ; } } , onDestroy ( fragment ) { ( df as any ) . nListener = null ; if ( owner ) { if ( owner . isLoaded ) { owner . callUnloaded ( ) ; } owner . _isAddedToNativeVisualTree = false ; owner . _tearDownUI ( true ) ; } } } ) ; const df = new com . nativescript . material . bottomsheet . BottomSheetDialogFragment ( ) ; df . setListener ( dfListener ) ; ( df as any ) . nListener = dfListener ; this . _bottomSheetFragment = df ; this . _raiseShowingBottomSheetEvent ( ) ; df . show ( parent . _getRootFragmentManager ( ) , domId . toString ( ) ) ; } } let mixinInstalled = false ; export function overrideBottomSheet ( ) { applyMixins ( View , [ ViewWithBottomSheetBase , ViewWithBottomSheet ] ) ; } export function install ( ) { if ( ! mixinInstalled ) { mixinInstalled = true ; overrideBottomSheet ( ) ; } }