diff --git a/node/buildSrcCordova.js b/node/buildSrcCordova.js index 48a31c353..d0166ed8a 100644 --- a/node/buildSrcCordova.js +++ b/node/buildSrcCordova.js @@ -56,26 +56,26 @@ function getVersionsFromConfigXML () { let regex = /version="(.*?)"/; let found = data.match(regex); if (found.length > 0) { - console.log('version from config.xml: ', found[1]); + console.log('> Cordova: version from config.xml: ', found[1]); versions.version = found[1]; } else { - console.log('version from config.xml: error'); + console.log('> Cordova: version from config.xml: error'); } regex = /ios-CFBundleVersion="(.*?)"/; found = data.match(regex); - if (found.length > 0) { - console.log('ios-CFBundleVersion from config.xml: ', found[1]); + if (found && found.length > 0) { + console.log('> Cordova: ios-CFBundleVersion from config.xml: ', found[1]); versions.iosBundleVersion = found[1]; } else { - console.log('ios-CFBundleVersion from config.xml: error'); + console.log('> Cordova: ios-CFBundleVersion from config.xml: error'); } regex = /android-versionCode="(.*?)"/; found = data.match(regex); - if (found.length > 0) { - console.log('android-versionCode from config.xml: ', found[1]); + if (found && found.length > 0) { + console.log('> Cordova: android-versionCode from config.xml: ', found[1]); versions.androidBundleVersion = found[1]; } else { - console.log('android-versionCode from config.xml: error'); + console.log('> Cordova: android-versionCode from config.xml: error'); } return versions; } @@ -178,7 +178,7 @@ function fileRewriterForCordova (path, versions) { if (deleteFiles.includes(path)) { fs.remove(path); - console.log(`rm file ${path}`); + console.log(`> Removed: rm file ${path}`); // } else if (dummySubstituteFiles.includes(path)) { // Removes files that have includes that cause problems in cordova -- these were Stripe related, // but the stripe problem no longer manifested in Oct 2025, and Dale wanted the non-functional @@ -234,13 +234,13 @@ fs.remove('./build').then(() => { if (!(out.length === 1 && out[1] === undefined)) { console.log('> Cordova: Files that (incorrectly) still contain React.lazy: '); console.log(out); - console.log('> Cordova: The files listed above, need to be fixed before proceeding!'); // Or the regex needs adjustment + console.error('> Cordova: The files listed above, need to be fixed before proceeding!'); // Or the regex needs adjustment } }); }); }); } catch (err) { - console.log(err); + console.error(`> Cordova caught error: ${err}`); } }); }); diff --git a/node/initialSteps.js b/node/initialSteps.js index 4588edc5a..ea3308112 100644 --- a/node/initialSteps.js +++ b/node/initialSteps.js @@ -2,7 +2,7 @@ const fs = require('fs'); const { promises: fsPromises } = require('fs'); const isWebApp = !process.env.npm_lifecycle_script.includes('CORDOVA=1'); -console.log(isWebApp ? 'initialSteps -- WebApp compilation' : '> Cordova: Cordova compilation'); +console.log(isWebApp ? 'Info.plist initialSteps -- WebApp compilation' : '> Cordova: Cordova compilation'); // Creates the compileDate.js file that contains the compile date as a string, so it can be displayed where wanted in the app. const d = new Date(); diff --git a/node/unSymLinkIOS.sh b/node/unSymLinkIOS.sh index 84dae28ff..26a659532 100644 --- a/node/unSymLinkIOS.sh +++ b/node/unSymLinkIOS.sh @@ -1,5 +1,5 @@ # This suddenly become necessary with XCode 15 and iOS 17, on October 25, 2023 -echo 'copying files and removing symlinks in WeVoteCordova/platforms/ios/www' +echo '> Cordova: copying files and removing symlinks in WeVoteCordova/platforms/ios/www' cd ../WeVoteCordova/platforms/ios/www || exit rm bundle.js cp ../../../../WebApp/build/bundle.js . diff --git a/src/App.jsx b/src/App.jsx index 85f75bc19..9fca9dc2e 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -12,7 +12,7 @@ import VoterSessionActions from './js/actions/VoterSessionActions'; import muiTheme from './js/common/components/Style/muiTheme'; import LoadingWheelComp from './js/common/components/Widgets/LoadingWheelComp'; import AppObservableStore, { messageService } from './js/common/stores/AppObservableStore'; -import { hasDynamicIsland, hasIPhoneNotch, heightOfIOSSpacer } from './js/common/utils/cordovaUtils'; +import { hasDynamicIsland, hasCordovaNotch, heightOfCordovaSpacer } from './js/common/utils/cordovaUtils'; import historyPush from './js/common/utils/historyPush'; import { isWeVoteMarketingSite, normalizedHref } from './js/common/utils/hrefUtils'; import initializejQuery from './js/common/utils/initializejQuery'; @@ -221,7 +221,7 @@ class App extends Component { if (isCordova()) { console.log(`Cordova: window.device ${JSON.stringify(window.device)}`); - console.log(`Cordova: Header, isIOS ${hasDynamicIsland()} (${heightOfIOSSpacer()}), hasIPhoneNotch (or AndroidNotch) ${hasIPhoneNotch()}`); + console.log(`Cordova: Header, isIOS ${hasDynamicIsland()}, heightOfCordovaSpacer ${heightOfCordovaSpacer()}), hasCordovaNotch ${hasCordovaNotch()}`); } this.acceptURLVariables(); @@ -536,8 +536,8 @@ class App extends Component { - - + + diff --git a/src/js/common/components/Navigation/ChallengeHeaderSimple.jsx b/src/js/common/components/Navigation/ChallengeHeaderSimple.jsx index 7e1d9bc3a..ebb3d26b2 100644 --- a/src/js/common/components/Navigation/ChallengeHeaderSimple.jsx +++ b/src/js/common/components/Navigation/ChallengeHeaderSimple.jsx @@ -45,7 +45,7 @@ function ChallengeHeaderSimple (props) { {!hideCloseIcon && ( - +
-
+ )} @@ -157,7 +157,7 @@ const ChallengeTitleRow = styled('div')` margin-bottom: 16px; `; -const CloseDrawerIconWrapper = styled('div')` +const CloseDrawerIconWrapperChallenger = styled('div')` display: flex; justify-content: flex-end; `; diff --git a/src/js/common/components/Settings/SettingsVerifySecretCode.jsx b/src/js/common/components/Settings/SettingsVerifySecretCode.jsx index 39803b2e3..df44d28be 100644 --- a/src/js/common/components/Settings/SettingsVerifySecretCode.jsx +++ b/src/js/common/components/Settings/SettingsVerifySecretCode.jsx @@ -8,7 +8,7 @@ import PropTypes from 'prop-types'; import React, { Component } from 'react'; import styled from 'styled-components'; import VoterActions from '../../../actions/VoterActions'; -import { hasIPhoneNotch, isIOS, isIPhone4in } from '../../utils/cordovaUtils'; +import { hasCordovaNotch, isIOS, isIPhone4in } from '../../utils/cordovaUtils'; import { isCordova, isWebApp } from '../../utils/isCordovaOrWebApp'; import { renderLog } from '../../utils/logging'; import VoterStore from '../../../stores/VoterStore'; @@ -758,7 +758,7 @@ SettingsVerifySecretCode.propTypes = { const styles = (theme) => ({ dialogPaper: { - marginTop: hasIPhoneNotch() ? 68 : 48, + marginTop: hasCordovaNotch() ? 68 : 48, [theme.breakpoints.up('sm')]: { maxWidth: '720px', width: '85%', diff --git a/src/js/common/utils/cordovaUtils.js b/src/js/common/utils/cordovaUtils.js index 1d328575e..45bea22ea 100644 --- a/src/js/common/utils/cordovaUtils.js +++ b/src/js/common/utils/cordovaUtils.js @@ -356,14 +356,18 @@ export function isIPadMini () { return false; } -export function heightOfIOSSpacer (asString = false) { - if (isIOS()) { +export function heightOfCordovaSpacer (asString = false) { + let height = 0; + if (isCordova()) { if (isIOS() && !isIOSAppOnMac()) { - const params = getThisAppleDeviceParameters(); - return asString ? `${params.iOSSpacer}px` : params.iOSSpacer; + const { iOSSpacer } = getThisAppleDeviceParameters(); + height = iOSSpacer; + } else if (isAndroid()) { + height = window.androidNotchCutout ? window.androidNotchInset : 0; } } - return 0; + // console.log(`heightOfCordovaSpacer '${asString ? `${height}px` : height}'`); + return asString ? `${height}px` : height; } export function isCordovaPhone () { @@ -395,32 +399,8 @@ export function isIPadGiantSize () { return false; } -export function isAndroidNotch () { - if (window.device === undefined) { - return false; - } - const { device: { model, uuid } } = window; - // There is an edge-to-edge setting for android, but it will go away in Android 16 in 2025, we have to do this - // https://stackoverflow.com/questions/79382767/prevent-edge-to-edge-behaviour-after-android-sdk-35 - const notchedModels = [ - 'Pixel 7', // From Browserstack Cordova app device dialog - 'Pixel 9', // From Browserstack logcat - 'Pixel 9', // From Browserstack logcat - 'Pixel 9 Pro', // From Browserstack logcat - 'Pixel 9 Pro XL', // From Browserstack logcat - 'Pixel 10', // From Browserstack logcat - 'Pixel 10 Pro', // From Browserstack logcat - 'Pixel 10 Pro XL', // From Browserstack logcat - ]; - const simulatorUUIDs = [ // These change when you update Android Studio - 'ba09ecb05c77f653', - '6d9df9c89e647862', - ]; - if (notchedModels.includes(model) || simulatorUUIDs.includes(uuid)) { - logMatch('isAndroidNotch === true for ', model, uuid); - return true; - } - return false; +export function hasAndroidNotch () { + return window.androidNotchCutout; } export function hasDynamicIsland () { @@ -436,19 +416,23 @@ export function hasDynamicIsland () { return false; } -export function hasIPhoneNotch () { - if (!isIOS()) return false; - // Notched models === from the iPhone X up to the iPhone 14 and iPhone SE (2022). - // Specifically, this includes the iPhone X, XR, XS, 11, 12, 13 series, iPhone 14 and 14 Plus, and the iPhone SE (2022). - const params = getThisAppleDeviceParameters(); - const marketingInt = parseInt(params.marketingNumber) || 0; - const isPro = params.name.includes('Pro'); - const lettered = ['X', 'XR', 'XS', 'SE']; // Too simple of a test to handle old SE versions, but those are mostly gone - return !hasDynamicIsland() && ( - lettered.includes(params.marketingNumber) || - (marketingInt === 14 && !isPro) || - (marketingInt >= 11 && marketingInt <= 13) - ); +export function hasCordovaNotch () { + if (isAndroid()) { + return hasAndroidNotch(); + } else if (isIOS()) { + // Notched models === from the iPhone X up to the iPhone 14 and iPhone SE (2022). + // Specifically, this includes the iPhone X, XR, XS, 11, 12, 13 series, iPhone 14 and 14 Plus, and the iPhone SE (2022). + const params = getThisAppleDeviceParameters(); + const marketingInt = parseInt(params.marketingNumber) || 0; + const isPro = params.name.includes('Pro'); + const lettered = ['X', 'XR', 'XS', 'SE']; // Too simple of a test to handle old SE versions, but those are mostly gone + return !hasDynamicIsland() && ( + lettered.includes(params.marketingNumber) || + (marketingInt === 14 && !isPro) || + (marketingInt >= 11 && marketingInt <= 13) + ); + } + return false; } export function isIOsSmallerThanPlus () { @@ -519,39 +503,6 @@ export function getAndroidSize () { return androidSizeString; } -export function hasAndroidNotch () { - // https://deviceatlas.com/blog/list-of-user-agent-strings (last letter U, like SM-G988U, is a country code ... USA) - const ua = navigator.userAgent.toLowerCase(); - if (ua.includes('SM-S908') || // Samsung Galaxy S22 Ultra - ua.includes('SM-S906') || // Samsung Galaxy S22+ - ua.includes('SM-S901') || // Samsung Galaxy S22 - ua.includes('SM-G996') || // Samsung Galaxy S21 - ua.includes('SM-G980') || // Samsung Galaxy S20 - ua.includes('SM-G973')) { // Samsung Galaxy S10 - return true; - } - - // window.device.model: "sdk_gphone64_arm64" - - if (androidPixels === 4446720) { - logMatch('Android Samsung Galaxy S22 Ultra (or S22+) detected by pixel size'); - return true; - } else if (androidPixels === 2527200) { - logMatch('Android Samsung Galaxy S22 detected by pixel size'); // 1440 x 3040 - return true; - } else if (androidPixels === 2562000) { - logMatch('Android Samsung Galaxy S21 detected by pixel size'); // 1080 x 2400 - return true; - } else if (androidPixels === 4608000) { - logMatch('Android Samsung Galaxy S20 Ultra detected by pixel size'); - return true; - } else if (androidPixels === 4377600) { - logMatch('Android Samsung Galaxy S10 detected by pixel size'); // 1080x2340 - return true; - } - return false; -} - export function isAndroidSizeSM () { if (isAndroid()) { if (getAndroidSize() === '--sm') { @@ -680,7 +631,7 @@ if (isSimulator()) { export function getToastClass () { let toastClass = ''; - if (hasIPhoneNotch()) { + if (hasCordovaNotch()) { toastClass = 'app-toast-cordova__iphone-notch'; } else if (isIOS()) { toastClass = 'app-toast-cordova__iphone'; diff --git a/src/js/components/Activity/ActivityTidbitDrawer.jsx b/src/js/components/Activity/ActivityTidbitDrawer.jsx index e56d61b72..ddaccd04e 100644 --- a/src/js/components/Activity/ActivityTidbitDrawer.jsx +++ b/src/js/components/Activity/ActivityTidbitDrawer.jsx @@ -77,7 +77,7 @@ class ActivityTidbitDrawer extends Component { anchor="right" classes={{ paper: classes.drawerClasses }} direction="left" - id="share-menu" + id="activityTidbit" onClose={this.closeActivityTidbitDrawer} open={modalOpen} > diff --git a/src/js/components/Ballot/PositionDrawer.jsx b/src/js/components/Ballot/PositionDrawer.jsx index d661470db..fe032ad49 100644 --- a/src/js/components/Ballot/PositionDrawer.jsx +++ b/src/js/components/Ballot/PositionDrawer.jsx @@ -11,7 +11,8 @@ import MeasureActions from '../../actions/MeasureActions'; import OrganizationActions from '../../actions/OrganizationActions'; import VoterGuideActions from '../../actions/VoterGuideActions'; import apiCalming from '../../common/utils/apiCalming'; -import { hasIPhoneNotch } from '../../common/utils/cordovaUtils'; +import convertToInteger from '../../common/utils/convertToInteger'; +import { hasCordovaNotch, heightOfCordovaSpacer } from '../../common/utils/cordovaUtils'; import { normalizedHref } from '../../common/utils/hrefUtils'; import { isWebApp } from '../../common/utils/isCordovaOrWebApp'; import { renderLog } from '../../common/utils/logging'; @@ -20,11 +21,8 @@ import BallotStore from '../../stores/BallotStore'; import CandidateStore from '../../stores/CandidateStore'; import IssueStore from '../../stores/IssueStore'; import MeasureStore from '../../stores/MeasureStore'; -// import OrganizationStore from '../../stores/OrganizationStore'; import VoterGuideStore from '../../stores/VoterGuideStore'; import VoterStore from '../../stores/VoterStore'; -import { cordovaDrawerTopMargin } from '../../utils/cordovaOffsets'; -import convertToInteger from '../../common/utils/convertToInteger'; const DelayedLoad = React.lazy(() => import(/* webpackChunkName: 'DelayedLoad' */ '../../common/components/Widgets/DelayedLoad')); const PositionItem = React.lazy(() => import(/* webpackChunkName: 'PositionItem' */ './PositionItem')); @@ -291,7 +289,7 @@ PositionDrawer.propTypes = { const styles = () => ({ drawer: { - marginTop: cordovaDrawerTopMargin(), + marginTop: `${heightOfCordovaSpacer(true)} !important`, maxWidth: '550px !important', '& *': { maxWidth: '550px !important', @@ -305,7 +303,7 @@ const styles = () => ({ }, dialogPaper: { display: 'block', - marginTop: hasIPhoneNotch() ? 68 : 48, + marginTop: hasCordovaNotch() ? 68 : 48, minWidth: '100%', maxWidth: '100%', width: '100%', diff --git a/src/js/components/Ballot/SelectBallotModal.jsx b/src/js/components/Ballot/SelectBallotModal.jsx index 372013b44..8a62471cf 100644 --- a/src/js/components/Ballot/SelectBallotModal.jsx +++ b/src/js/components/Ballot/SelectBallotModal.jsx @@ -6,7 +6,7 @@ import PropTypes from 'prop-types'; import React, { Component, Suspense } from 'react'; import styled from 'styled-components'; import AnalyticsActions from '../../actions/AnalyticsActions'; -import { hasIPhoneNotch } from '../../common/utils/cordovaUtils'; +import { hasCordovaNotch } from '../../common/utils/cordovaUtils'; import { displayNoneIfSmallerThanDesktop } from '../../common/utils/isMobileScreenSize'; import { renderLog } from '../../common/utils/logging'; import AppObservableStore, { messageService } from '../../common/stores/AppObservableStore'; @@ -204,7 +204,7 @@ const styles = (theme) => ({ }, }, dialogPaper: { - marginTop: hasIPhoneNotch() ? 68 : 48, + marginTop: hasCordovaNotch() ? 68 : 48, minHeight: '80%', maxHeight: '90%', height: '80%', diff --git a/src/js/components/CompleteYourProfile/AdviserIntroModal.jsx b/src/js/components/CompleteYourProfile/AdviserIntroModal.jsx index ddb9ff9dc..edd7a9c6e 100644 --- a/src/js/components/CompleteYourProfile/AdviserIntroModal.jsx +++ b/src/js/components/CompleteYourProfile/AdviserIntroModal.jsx @@ -5,7 +5,7 @@ import withStyles from '@mui/styles/withStyles'; import withTheme from '@mui/styles/withTheme'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; -import { hasIPhoneNotch } from '../../common/utils/cordovaUtils'; +import { hasCordovaNotch } from '../../common/utils/cordovaUtils'; import { renderLog } from '../../common/utils/logging'; import { ModalTitleType1, ModalTitleAreaType1 } from '../Style/ModalType1Styles'; @@ -67,7 +67,7 @@ AdviserIntroModal.propTypes = { const styles = () => ({ dialogPaper: { - marginTop: hasIPhoneNotch() ? 68 : 48, + marginTop: hasCordovaNotch() ? 68 : 48, '@media (min-width: 576px)': { maxWidth: '600px', width: '90%', diff --git a/src/js/components/CompleteYourProfile/FirstPositionIntroModal.jsx b/src/js/components/CompleteYourProfile/FirstPositionIntroModal.jsx index d1d6f332c..16593a81f 100644 --- a/src/js/components/CompleteYourProfile/FirstPositionIntroModal.jsx +++ b/src/js/components/CompleteYourProfile/FirstPositionIntroModal.jsx @@ -6,7 +6,7 @@ import withTheme from '@mui/styles/withTheme'; import PropTypes from 'prop-types'; import React, { Component, Suspense } from 'react'; import VoterActions from '../../actions/VoterActions'; -import { hasIPhoneNotch } from '../../common/utils/cordovaUtils'; +import { hasCordovaNotch } from '../../common/utils/cordovaUtils'; import { normalizedHref } from '../../common/utils/hrefUtils'; import { renderLog } from '../../common/utils/logging'; import { ContinueButtonType1Wrapper, ModalTitleType1, ModalTitleAreaType1 } from '../Style/ModalType1Styles'; @@ -155,7 +155,7 @@ FirstPositionIntroModal.propTypes = { const styles = () => ({ dialogPaper: { - marginTop: hasIPhoneNotch() ? 68 : 48, + marginTop: hasCordovaNotch() ? 68 : 48, '@media (min-width: 576px)': { maxWidth: '600px', width: '90%', diff --git a/src/js/components/CompleteYourProfile/HowItWorksModal.jsx b/src/js/components/CompleteYourProfile/HowItWorksModal.jsx index 9a18a9bc9..702b5b4f2 100644 --- a/src/js/components/CompleteYourProfile/HowItWorksModal.jsx +++ b/src/js/components/CompleteYourProfile/HowItWorksModal.jsx @@ -7,7 +7,7 @@ import React, { Component, Suspense } from 'react'; import TagManager from 'react-gtm-module'; import styled from 'styled-components'; import VoterActions from '../../actions/VoterActions'; -import { heightOfIOSSpacer } from '../../common/utils/cordovaUtils'; +import { heightOfCordovaSpacer } from '../../common/utils/cordovaUtils'; import isMobileScreenSize from '../../common/utils/isMobileScreenSize'; import { renderLog } from '../../common/utils/logging'; import VoterConstants from '../../constants/VoterConstants'; @@ -99,7 +99,7 @@ HowItWorksModal.propTypes = { const styles = () => ({ dialogPaper: { - marginTop: heightOfIOSSpacer() ? heightOfIOSSpacer() : 48, + marginTop: heightOfCordovaSpacer() ? heightOfCordovaSpacer() : 48, '@media (min-width: 576px)': { maxWidth: '600px', width: '90%', diff --git a/src/js/components/CompleteYourProfile/PersonalizedScoreIntroModal.jsx b/src/js/components/CompleteYourProfile/PersonalizedScoreIntroModal.jsx index 10b4571e3..2488319ab 100644 --- a/src/js/components/CompleteYourProfile/PersonalizedScoreIntroModal.jsx +++ b/src/js/components/CompleteYourProfile/PersonalizedScoreIntroModal.jsx @@ -6,7 +6,7 @@ import withTheme from '@mui/styles/withTheme'; import PropTypes from 'prop-types'; import React, { Component, Suspense } from 'react'; import VoterActions from '../../actions/VoterActions'; -import { hasIPhoneNotch } from '../../common/utils/cordovaUtils'; +import { hasCordovaNotch } from '../../common/utils/cordovaUtils'; import { normalizedHref } from '../../common/utils/hrefUtils'; import { isCordova } from '../../common/utils/isCordovaOrWebApp'; import { renderLog } from '../../common/utils/logging'; @@ -86,7 +86,7 @@ const styles = () => ({ height: isCordova() ? '83%' : '90%', margin: '0 auto', padding: '0 !important', - marginTop: hasIPhoneNotch() ? 68 : 48, + marginTop: hasCordovaNotch() ? 68 : 48, transitionDuration: '.25s', '@media (min-width: 400px)': { // Doesn't work in cordova width: '90%', diff --git a/src/js/components/CompleteYourProfile/ValuesIntroModal.jsx b/src/js/components/CompleteYourProfile/ValuesIntroModal.jsx index 897dfe3ba..7aabc1ed0 100644 --- a/src/js/components/CompleteYourProfile/ValuesIntroModal.jsx +++ b/src/js/components/CompleteYourProfile/ValuesIntroModal.jsx @@ -7,7 +7,7 @@ import PropTypes from 'prop-types'; import React, { Component, Suspense } from 'react'; import IssueActions from '../../actions/IssueActions'; import VoterActions from '../../actions/VoterActions'; -import { hasIPhoneNotch } from '../../common/utils/cordovaUtils'; +import { hasCordovaNotch } from '../../common/utils/cordovaUtils'; import { renderLog } from '../../common/utils/logging'; import { ContinueButtonType1Wrapper, ExplanationTextType1, ExplanationTextLighterType1, ModalTitleType1, ModalTitleAreaType1 } from '../Style/ModalType1Styles'; import VoterConstants from '../../constants/VoterConstants'; @@ -121,7 +121,7 @@ ValuesIntroModal.propTypes = { const styles = () => ({ dialogPaper: { - marginTop: hasIPhoneNotch() ? 68 : 48, + marginTop: hasCordovaNotch() ? 68 : 48, '@media (min-width: 576px)': { maxWidth: '600px', width: '90%', diff --git a/src/js/components/Drawers/DrawerTemplateHeaderProfile.jsx b/src/js/components/Drawers/DrawerTemplateHeaderProfile.jsx index eedc6f52a..9d112c337 100644 --- a/src/js/components/Drawers/DrawerTemplateHeaderProfile.jsx +++ b/src/js/components/Drawers/DrawerTemplateHeaderProfile.jsx @@ -6,10 +6,9 @@ import React, { useCallback, useEffect, useState } from 'react'; import styled from 'styled-components'; import DesignTokenColors from '../../common/components/Style/DesignTokenColors'; import AppObservableStore, { messageService } from '../../common/stores/AppObservableStore'; -import { hasIPhoneNotch, isIPadSmallerThan13 } from '../../common/utils/cordovaUtils'; +import { hasCordovaNotch, heightOfCordovaSpacer, isIPadSmallerThan13 } from '../../common/utils/cordovaUtils'; import { renderLog } from '../../common/utils/logging'; -import { cordovaDrawerTopMargin } from '../../utils/cordovaOffsets'; -import { DrawerHeaderAnimateDownInnerContainer, DrawerHeaderAnimateDownOuterContainer, DrawerHeaderWrapper, DrawerTitle } from '../Style/drawerLayoutStyles'; +import { CloseDrawerIconWrapper, DrawerHeaderAnimateDownInnerContainer, DrawerHeaderAnimateDownOuterContainer, DrawerHeaderWrapper, DrawerTitle } from '../Style/drawerLayoutStyles'; const DrawerTemplateHeaderProfile = (props) => { const { classes, drawerId, drawerOpenGlobalVariableName, headerFixedJsx, headerTitleJsx, mainContentJsx, onDrawerClose } = props; @@ -133,7 +132,7 @@ DrawerTemplateHeaderProfile.propTypes = { const styles = () => ({ drawer: { - marginTop: cordovaDrawerTopMargin(), + marginTop: `${heightOfCordovaSpacer(true)} !important`, width: '80%', }, dialogPaper: { @@ -145,7 +144,7 @@ const styles = () => ({ maxHeight: '100%', height: '100%', margin: '0 auto', - marginTop: hasIPhoneNotch() ? 68 : 48, + marginTop: hasCordovaNotch() ? 68 : 48, '@media (min-width: 577px)': { maxWidth: '550px', width: '90%', @@ -226,9 +225,4 @@ const DrawerTemplateHeaderProfileWrapper = styled('div')` min-width: 300px; `; -const CloseDrawerIconWrapper = styled('div')` - display: flex; - justify-content: flex-end; -`; - export default withStyles(styles)(DrawerTemplateHeaderProfile); diff --git a/src/js/components/FriendIntro/FAQModal.jsx b/src/js/components/FriendIntro/FAQModal.jsx index c0768dbf2..056da696d 100644 --- a/src/js/components/FriendIntro/FAQModal.jsx +++ b/src/js/components/FriendIntro/FAQModal.jsx @@ -6,7 +6,7 @@ import PropTypes from 'prop-types'; import React, { Component, Suspense } from 'react'; import styled from 'styled-components'; import FAQBody from '../../common/components/FAQBody'; -import { hasIPhoneNotch } from '../../common/utils/cordovaUtils'; +import { hasCordovaNotch } from '../../common/utils/cordovaUtils'; import { renderLog } from '../../common/utils/logging'; // const FAQ = React.lazy(() => import(/* webpackChunkName: 'FAQModal' */ '../../components/FriendIntro/FAQModal')); @@ -71,7 +71,7 @@ FAQModal.propTypes = { const styles = () => ({ dialogPaper: { - marginTop: hasIPhoneNotch() ? 68 : 48, + marginTop: hasCordovaNotch() ? 68 : 48, '@media (min-width: 576px)': { maxWidth: '600px', width: '90%', diff --git a/src/js/components/Friends/AskFriendsModal.jsx b/src/js/components/Friends/AskFriendsModal.jsx index e4e037062..de6b4337e 100644 --- a/src/js/components/Friends/AskFriendsModal.jsx +++ b/src/js/components/Friends/AskFriendsModal.jsx @@ -15,7 +15,7 @@ import FriendList from './FriendList'; import FriendActions from '../../actions/FriendActions'; import apiCalming from '../../common/utils/apiCalming'; import { formatDateMMMDoYYYY } from '../../common/utils/dateFormat'; -import { hasIPhoneNotch } from '../../common/utils/cordovaUtils'; +import { hasCordovaNotch } from '../../common/utils/cordovaUtils'; import daysUntil from '../../common/utils/daysUntil'; import { renderLog } from '../../common/utils/logging'; import { ModalTitleType1 } from '../Style/ModalType1Styles'; @@ -38,7 +38,7 @@ class AskFriendsModal extends Component { numberOfIncreases: 0, numberOfItemsToDisplay: 20, searchFilterOn: false, - searchTerm: '', + // searchTerm: '', }; } @@ -144,7 +144,7 @@ class AskFriendsModal extends Component { this.setState({ currentFriendListFilteredBySearch: [], searchFilterOn: false, - searchTerm: '', + // searchTerm: '', }); } else { const searchTermLowercase = searchTerm.toLowerCase(); @@ -155,7 +155,7 @@ class AskFriendsModal extends Component { this.setState({ currentFriendListFilteredBySearch: searchedFriendList, searchFilterOn: true, - searchTerm, + // searchTerm, }); } } @@ -163,7 +163,7 @@ class AskFriendsModal extends Component { clearSearch = () => { this.setState({ searchFilterOn: false, - searchTerm: '', + // searchTerm: '', currentFriendListFilteredBySearch: [], }); } @@ -276,7 +276,7 @@ AskFriendsModal.propTypes = { const styles = () => ({ dialogPaper: { - marginTop: hasIPhoneNotch() ? 68 : 48, + marginTop: hasCordovaNotch() ? 68 : 48, '@media (min-width: 576px)': { maxWidth: '600px', width: '90%', diff --git a/src/js/components/Navigation/FooterBar.jsx b/src/js/components/Navigation/FooterBar.jsx index 239d7ece0..d280b3655 100644 --- a/src/js/components/Navigation/FooterBar.jsx +++ b/src/js/components/Navigation/FooterBar.jsx @@ -11,15 +11,15 @@ import AppObservableStore, { messageService } from '../../common/stores/AppObser import { isIOS } from '../../common/utils/cordovaUtils'; import historyPush from '../../common/utils/historyPush'; import { normalizedHref } from '../../common/utils/hrefUtils'; -import { isAndroid, isCordova } from '../../common/utils/isCordovaOrWebApp'; +import { isAndroid } from '../../common/utils/isCordovaOrWebApp'; import { renderLog } from '../../common/utils/logging'; import normalizedImagePath from '../../common/utils/normalizedImagePath'; import stringContains from '../../common/utils/stringContains'; +import webAppConfig from '../../config'; import FriendStore from '../../stores/FriendStore'; import VoterStore from '../../stores/VoterStore'; import { cordovaFooterHeight } from '../../utils/cordovaOffsets'; import ShareButtonFooter from '../Share/ShareButtonFooter'; -import webAppConfig from '../../config'; const nextReleaseFeaturesEnabled = webAppConfig.ENABLE_NEXT_RELEASE_FEATURES === undefined ? false : webAppConfig.ENABLE_NEXT_RELEASE_FEATURES; @@ -105,7 +105,7 @@ class FooterBar extends React.Component { // inPrivateLabelMode: false, // setState onAppObservableStoreChange is not working sometimes for some reason showingOneCompleteYourProfileModal: false, showSignInModal: false, - voterIsSignedIn: false, + // voterIsSignedIn: false, }; } @@ -169,15 +169,15 @@ class FooterBar extends React.Component { } onVoterStoreChange () { - const voter = VoterStore.getVoter(); - const voterIsSignedIn = voter.is_signed_in || false; - this.setState({ - voterIsSignedIn, - }); + // const voter = VoterStore.getVoter(); + // const voterIsSignedIn = voter.is_signed_in || false; + // this.setState({ + // voterIsSignedIn, + // }); } handleChange = (event, value) => { - if (isCordova()) { + if (isIOS()) { const { impact } = window.TapticEngine; impact({ style: 'heavy', // light | medium | heavy @@ -273,12 +273,12 @@ class FooterBar extends React.Component { // console.log('friendInvitationsSentToMeCount:', friendInvitationsSentToMeCount); // If NOT signed in, turn Discuss off and How It Works on let donateVisible; - if (isCordova() || inPrivateLabelMode) { - donateVisible = true; // 2025-06-17 Enabling donations, we hear it is now permissible for nonprofits in iOS & Android + if (inPrivateLableMode) { + donateVisible = false; // Turn off donate link if an org has private labeled WeVote } else { - donateVisible = true; + donateVisible = true; // 2025-06-17 Enabling donations, we hear it is now permissible for nonprofits in iOS & Android + // console.log('--------- Footer bar donateVisible ', donateVisible, 'squadsVisible', squadsVisible); } - // console.log('--------- Footer bar donateVisible ', donateVisible, 'squadsVisible', squadsVisible); return ( {showShareButtonFooter && ( diff --git a/src/js/components/Navigation/Header.jsx b/src/js/components/Navigation/Header.jsx index 951375431..d3385b548 100644 --- a/src/js/components/Navigation/Header.jsx +++ b/src/js/components/Navigation/Header.jsx @@ -4,7 +4,7 @@ import styled from 'styled-components'; import VoterActions from '../../actions/VoterActions'; import AppObservableStore, { messageService } from '../../common/stores/AppObservableStore'; import apiCalming from '../../common/utils/apiCalming'; -import { isAndroidSizeWide, isCordovaWide, isIOS, isIOSAppOnMac, isIPad } from '../../common/utils/cordovaUtils'; +import { isAndroidSizeWide, isCordovaWide, isIOSAppOnMac, isIPad } from '../../common/utils/cordovaUtils'; import historyPush from '../../common/utils/historyPush'; import { normalizedHref } from '../../common/utils/hrefUtils'; import { isCordova, isWebApp } from '../../common/utils/isCordovaOrWebApp'; @@ -15,7 +15,7 @@ import stringContains from '../../common/utils/stringContains'; import VoterStore from '../../stores/VoterStore'; import { dumpCssFromId } from '../../utils/appleSiliconUtils'; import { getApplicationViewBooleans, weVoteBrandingOff } from '../../utils/applicationUtils'; -import { HeadroomWrapper, IOSTopOfScreenSpacer } from '../Style/pageLayoutStyles'; +import { CordovaTopOfScreenSpacer, HeadroomWrapper } from '../Style/pageLayoutStyles'; import HeaderBar from './HeaderBar'; @@ -251,7 +251,7 @@ export default class Header extends Component { } return (
- {isIOS() ? : ''} + {isCordova() ? : ''}
}> @@ -310,7 +310,7 @@ export default class Header extends Component { // console.log('isCordovaWide()', isCordovaWide(), 'innerWidth', innerWidth, 'tabMin', tabMin, 'isTablet()', isTablet()); return (
- {isIOS() ? : ''} + {isCordova() ? : ''}
{ showBackToSettingsDesktop && ( @@ -416,7 +416,7 @@ export default class Header extends Component { return (
- {isIOS() ? : ''} + {isCordova() ? : ''} {/*
*/}
@@ -483,7 +483,7 @@ export default class Header extends Component { // console.log('Header not in any mode, headerNotVisible:', headerNotVisible); return (
- {isIOS() ? : ''} + {isCordova() ? : ''}
{(showNotificationBannerAboveHeader && isCandidatePage) && ( diff --git a/src/js/components/Navigation/HeaderBackTo.jsx b/src/js/components/Navigation/HeaderBackTo.jsx index 85173b7ce..7948371cc 100644 --- a/src/js/components/Navigation/HeaderBackTo.jsx +++ b/src/js/components/Navigation/HeaderBackTo.jsx @@ -8,11 +8,10 @@ import VoterGuideActions from '../../actions/VoterGuideActions'; import LazyImage from '../../common/components/LazyImage'; import AppObservableStore, { messageService } from '../../common/stores/AppObservableStore'; import apiCalming from '../../common/utils/apiCalming'; -import { heightOfIOSSpacer, isIOSAppOnMac, isIPad } from '../../common/utils/cordovaUtils'; +import { heightOfCordovaSpacer, isIOSAppOnMac, isIPad } from '../../common/utils/cordovaUtils'; import historyPush from '../../common/utils/historyPush'; import { normalizedHref } from '../../common/utils/hrefUtils'; import { isCordova, isWebApp } from '../../common/utils/isCordovaOrWebApp'; -import isMobileScreenSize from '../../common/utils/isMobileScreenSize'; import { renderLog } from '../../common/utils/logging'; import stringContains from '../../common/utils/stringContains'; import voterPhoto from '../../common/utils/voterPhoto'; @@ -201,7 +200,7 @@ class HeaderBackTo extends Component { const voterPhotoUrlMedium = voterPhoto(voter); const pathname = normalizedHref(); const shareButtonInHeader = pathname && stringContains('/office', pathname.toLowerCase()); - const pad = `${heightOfIOSSpacer(true)} 15px 0 0`; + const pad = `${heightOfCordovaSpacer(true)} 15px 0 0`; const cordovaStyles = { marginLeft: 0, padding: pad, diff --git a/src/js/components/Navigation/HeaderBackToBallot.jsx b/src/js/components/Navigation/HeaderBackToBallot.jsx index a0ce7ee3f..d3d95a8f5 100644 --- a/src/js/components/Navigation/HeaderBackToBallot.jsx +++ b/src/js/components/Navigation/HeaderBackToBallot.jsx @@ -13,7 +13,6 @@ import { isIOSAppOnMac, isIPad, isIPadGiantSize } from '../../common/utils/cordo import historyPush from '../../common/utils/historyPush'; import { normalizedHref, normalizedHrefPage } from '../../common/utils/hrefUtils'; import { isCordova, isWebApp } from '../../common/utils/isCordovaOrWebApp'; -import isMobileScreenSize from '../../common/utils/isMobileScreenSize'; import { renderLog } from '../../common/utils/logging'; import stringContains from '../../common/utils/stringContains'; import voterPhoto from '../../common/utils/voterPhoto'; @@ -709,7 +708,7 @@ class HeaderBackToBallot extends Component { // if (['candidate', 'office', 'measure'].includes(page)) { // if (isWebApp()) { // cname = `page-header ${!isMobileScreenSize() ? 'page-header__back-to-ballot' : ''}`; - // } else if (hasIPhoneNotch()) { + // } else if (hasCordovaNotch()) { // cname = 'page-header page-header__back-to-ballot-cordova page-header__cordova-iphonex'; // } else { // cname = 'page-header page-header__back-to-ballot-cordova page-header__cordova'; diff --git a/src/js/components/Navigation/HeaderBackToVoterGuides.jsx b/src/js/components/Navigation/HeaderBackToVoterGuides.jsx index 9d5f9e672..c9413ed02 100644 --- a/src/js/components/Navigation/HeaderBackToVoterGuides.jsx +++ b/src/js/components/Navigation/HeaderBackToVoterGuides.jsx @@ -8,7 +8,7 @@ import OrganizationActions from '../../actions/OrganizationActions'; import VoterGuideActions from '../../actions/VoterGuideActions'; import LazyImage from '../../common/components/LazyImage'; import apiCalming from '../../common/utils/apiCalming'; -import { hasIPhoneNotch } from '../../common/utils/cordovaUtils'; +import { hasCordovaNotch } from '../../common/utils/cordovaUtils'; import historyPush from '../../common/utils/historyPush'; import { normalizedHref } from '../../common/utils/hrefUtils'; import { isCordova, isWebApp } from '../../common/utils/isCordovaOrWebApp'; @@ -285,7 +285,7 @@ class HeaderBackToVoterGuides extends Component { ); let appBarCname = 'page-header page-header__voter-guide-creator'; - if (hasIPhoneNotch()) { + if (hasCordovaNotch()) { appBarCname = 'page-header page-header__cordova-iphonex page-header__voter-guide-creator'; } else if (isCordova()) { appBarCname = 'page-header page-header__cordova page-header__voter-guide-creator'; diff --git a/src/js/components/Navigation/HeaderBar.jsx b/src/js/components/Navigation/HeaderBar.jsx index d03d9baba..3c55229fe 100644 --- a/src/js/components/Navigation/HeaderBar.jsx +++ b/src/js/components/Navigation/HeaderBar.jsx @@ -13,7 +13,7 @@ import standardBoxShadow from '../../common/components/Style/standardBoxShadow'; import signInModalGlobalState from '../../common/components/Widgets/signInModalGlobalState'; import AppObservableStore, { messageService } from '../../common/stores/AppObservableStore'; import apiCalming from '../../common/utils/apiCalming'; -import { historyPush, isDeviceZoomed, isIOS } from '../../common/utils/cordovaUtils'; +import { historyPush } from '../../common/utils/cordovaUtils'; import { normalizedHrefPage } from '../../common/utils/hrefUtils'; import { isCordova, isWebApp } from '../../common/utils/isCordovaOrWebApp'; import isMobileScreenSize, { handleResize, isSmallTablet, isTablet } from '../../common/utils/isMobileScreenSize'; @@ -459,14 +459,14 @@ class HeaderBar extends Component { if (isSmallTablet()) { avatarStyle = { ...avatarStyle, paddingRight: 10 }; } - // console.log('HeaderBar hasNotch, scrolledDown, hasSubmenu', hasIPhoneNotch(), scrolledDown, displayTopMenuShadow()); + // console.log('HeaderBar hasNotch, scrolledDown, hasSubmenu', hasCordovaNotch(), scrolledDown, displayTopMenuShadow()); const displayMenu = !isMobileScreenSize() || isTablet(); // console.log('HeaderBar isMobileScreenSize(), isTablet()', isMobileScreenSize(), isTablet()); let donateValue; let donateVisible; - if (isCordova() || inPrivateLabelMode) { + if (inPrivateLabelMode) { donateValue = 3; - donateVisible = true; + donateVisible = false; } else { donateValue = 3; donateVisible = true; diff --git a/src/js/components/PositionItem/PositionPublicToggle.jsx b/src/js/components/PositionItem/PositionPublicToggle.jsx index 3811da8c6..1d87ed765 100644 --- a/src/js/components/PositionItem/PositionPublicToggle.jsx +++ b/src/js/components/PositionItem/PositionPublicToggle.jsx @@ -4,7 +4,7 @@ import PropTypes from 'prop-types'; import React, { Component, Suspense } from 'react'; import styled from 'styled-components'; import SupportActions from '../../actions/SupportActions'; -import { isAndroidSizeMD } from '../../common/utils/cordovaUtils'; // hasIPhoneNotch, +import { isAndroidSizeMD } from '../../common/utils/cordovaUtils'; // hasCordovaNotch, import isMobileScreenSize from '../../common/utils/isMobileScreenSize'; import { renderLog } from '../../common/utils/logging'; import SupportStore from '../../stores/SupportStore'; diff --git a/src/js/components/Ready/VoterPlanModal.jsx b/src/js/components/Ready/VoterPlanModal.jsx index 431203e31..5d33285b9 100644 --- a/src/js/components/Ready/VoterPlanModal.jsx +++ b/src/js/components/Ready/VoterPlanModal.jsx @@ -8,7 +8,7 @@ import styled from 'styled-components'; import VoterPlan from './VoterPlan'; import AnalyticsActions from '../../actions/AnalyticsActions'; import ReadyActions from '../../actions/ReadyActions'; -import { hasIPhoneNotch } from '../../common/utils/cordovaUtils'; +import { hasCordovaNotch } from '../../common/utils/cordovaUtils'; import { formatDateToMonthDayYear } from '../../common/utils/dateFormat'; import { renderLog } from '../../common/utils/logging'; import BallotStore from '../../stores/BallotStore'; @@ -288,7 +288,7 @@ VoterPlanModal.propTypes = { const styles = () => ({ dialogPaper: { - marginTop: hasIPhoneNotch() ? 68 : 48, + marginTop: hasCordovaNotch() ? 68 : 48, '@media (min-width: 576px)': { maxWidth: '600px', width: '90%', @@ -301,9 +301,9 @@ const styles = () => ({ minWidth: '100%', maxWidth: '100%', width: '100%', - minHeight: hasIPhoneNotch() ? '84%' : '90%', - maxHeight: hasIPhoneNotch() ? '84%' : '90%', - height: hasIPhoneNotch() ? '84%' : '90%', + minHeight: hasCordovaNotch() ? '84%' : '90%', + maxHeight: hasCordovaNotch() ? '84%' : '90%', + height: hasCordovaNotch() ? '84%' : '90%', margin: '0 auto', }, dialogContent: { diff --git a/src/js/components/Settings/ImageUploadModal.jsx b/src/js/components/Settings/ImageUploadModal.jsx index bcb4527c5..e25b8e18d 100644 --- a/src/js/components/Settings/ImageUploadModal.jsx +++ b/src/js/components/Settings/ImageUploadModal.jsx @@ -4,7 +4,7 @@ import withStyles from '@mui/styles/withStyles'; import withTheme from '@mui/styles/withTheme'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; -import { hasIPhoneNotch } from '../../common/utils/cordovaUtils'; +import { hasCordovaNotch } from '../../common/utils/cordovaUtils'; import { renderLog } from '../../common/utils/logging'; import { ModalTitleType1, ModalTitleAreaType1 } from '../Style/ModalType1Styles'; import DragAndDrop from './DragAndDrop'; @@ -81,7 +81,7 @@ ImageUploadModal.propTypes = { const styles = () => ({ dialogPaper: { - marginTop: hasIPhoneNotch() ? 68 : 48, + marginTop: hasCordovaNotch() ? 68 : 48, '@media (min-width: 576px)': { maxWidth: '600px', width: '90%', diff --git a/src/js/components/Settings/PaidAccountUpgradeModal.jsx b/src/js/components/Settings/PaidAccountUpgradeModal.jsx index da383df04..3604d729f 100644 --- a/src/js/components/Settings/PaidAccountUpgradeModal.jsx +++ b/src/js/components/Settings/PaidAccountUpgradeModal.jsx @@ -9,7 +9,7 @@ import React, { Component, Suspense } from 'react'; import DonateActions from '../../common/actions/DonateActions'; // TODO 5/11/21: import webAppConfig from '../../config'; import DonateStore from '../../common/stores/DonateStore'; -import { hasIPhoneNotch, isIOS } from '../../common/utils/cordovaUtils'; +import { hasCordovaNotch, isIOS } from '../../common/utils/cordovaUtils'; import extractNumber from '../../common/utils/extractNumber'; import { normalizedHref } from '../../common/utils/hrefUtils'; import { renderLog } from '../../common/utils/logging'; @@ -1061,7 +1061,7 @@ const styles = () => ({ marginRight: 8, }, dialogPaper: { - marginTop: hasIPhoneNotch() ? 68 : 48, + marginTop: hasCordovaNotch() ? 68 : 48, '@media (min-width: 769px)': { maxWidth: '600px', width: '85%', diff --git a/src/js/components/Share/ShareButtonFooter.jsx b/src/js/components/Share/ShareButtonFooter.jsx index 9824005c3..947cbb3b9 100644 --- a/src/js/components/Share/ShareButtonFooter.jsx +++ b/src/js/components/Share/ShareButtonFooter.jsx @@ -12,7 +12,7 @@ import { openSnackbar } from '../../common/components/Widgets/SnackNotifier'; import AppObservableStore, { messageService } from '../../common/stores/AppObservableStore'; import ShareStore from '../../common/stores/ShareStore'; import apiCalming from '../../common/utils/apiCalming'; -import { hasDynamicIsland, hasIPhoneNotch } from '../../common/utils/cordovaUtils'; +import { hasCordovaNotch, hasDynamicIsland } from '../../common/utils/cordovaUtils'; import { isAndroid, isCordova, isWebApp } from '../../common/utils/isCordovaOrWebApp'; import { renderLog } from '../../common/utils/logging'; import stringContains from '../../common/utils/stringContains'; @@ -24,9 +24,11 @@ import { shareBottomOffset } from '../../utils/cordovaOffsets'; import createMessageToFriendDefaults from '../../utils/createMessageToFriendDefaults'; import sortFriendListByMutualFriends from '../../utils/friendFunctions'; import isMobile from '../../utils/isMobile'; -import { CopyLink, getKindOfShareFromURL, getWhatAndHowMuchToShareDefault, saveActionShareAnalytics, ShareFacebook, SharePreviewFriends, shareStyles, ShareTwitter, ShareWeVoteFriends } from './shareButtonCommon'; // cordovaSocialSharingByEmail // cordovaSocialSharingByEmail +import { getKindOfShareFromURL } from './getKindOfShareFromURL'; +import { getWhatAndHowMuchToShareDefault } from './getWhatAndHowMuchToShareDefault'; +import { CopyLink, saveActionShareAnalytics, ShareFacebook, SharePreviewFriends, shareStyles, ShareTwitter, ShareWeVoteFriends } from './shareButtonCommon'; // cordovaSocialSharingByEmail // cordovaSocialSharingByEmail +import { generateShareLinks } from './sharedLinks'; import ShareModalOption from './ShareModalOption'; -import { generateShareLinks } from './ShareModalText'; import ShareModalTitleArea from './ShareModalTitleArea'; @@ -178,6 +180,7 @@ class ShareButtonFooter extends Component { }, () => this.openShareOptions()); // openShareOptions advances directly to share } + // eslint-disable-next-line no-unused-vars handleCloseShareButtonDrawer = (buttonId = '') => { this.setState({ openShareButtonDrawer: false, @@ -305,7 +308,7 @@ class ShareButtonFooter extends Component { onClose={this.handleCloseShareButtonDrawer} open={openShareButtonDrawer} > - +