#StackBounty: #ios #reactjs #safari #mobile-safari #progressive-web-apps React PWA Image Upload in Mobile Safari breaks application?

Bounty: 100

We were surprised we didn’t find any mention of this anywhere online, so we’re posting here in hopes we find a solution.

Using an iPhone with mobile safari is when we hit this issue running the 2 easy to follow tests below, one works, one doesn’t.

Here is the link
https://pwa-react.netlify.com/

Here are the 2 tests we run (both listed in the link), one works when not in PWA mode, and the other fails when in PWA mode.

Test #1: Works Perfectly (Expected Behaviour)

Visit https://pwa-react.netlify.com/ from iPhone in mobile safari
1. Make sure you have google drive on the phone but not logged in.
2. Click "Choose File". It will show you the list of options to choose from.
3. Click "Browse" to look for the photo.
4. Click "Cancel" and you're back here.
5. Click "Choose File" it will still show you the list of options to choose from.
   This works perfectly in mobile safari but NOT in PWA mode below.

Test #2: Does NOT Work (Unexpected Behaviour) (PWA)

Visit https://pwa-react.netlify.com/ from iPhone in mobile safari, hit the share
button, then add to home screen. This will add the PWA app on your phone. Open App.
1. Make sure you have google drive on the phone but not logged in.
2. Click "Choose File". It will show you the list of options to choose from.
3. Click "Browse" to look for the photo.
4. When it shows you the Google Drive logo with Sign In, double click the home 
   button, then go back to the PWA.
5. Click "Choose File" it will NOT show you the list of options to choose from. 
   This is now 100% broken.
   The ONLY way to fix it is to go to Settings>Safari>Clear History and Website Data (all the way down)
   How can we fix this so when the user hits "Choose File" it shows the list of 
   options to choose from in the PWA?

Screenshot #1: These are the options that appear in Test #1 and stop appearing in Test #2

enter image description here

Screenshot #2: This screen allows us to cancel in Test #1 but it disappears in Test #2

enter image description here

Any idea how to get Test #2 to work by allowing us to choose the upload options like in Screenshot #1 without breaking the app and having to go to safari settings to clear history and website data for it to function again?

PS – Here is the repository file https://github.com/MovingGifts/pwa-react/blob/master/src/App.js


Get this bounty!!!

#StackBounty: #reactjs #electron #windows-store-apps #windows-store #electron-builder How to fix 'The available app icons include a…

Bounty: 100

My electron-react project which I have open sourced here : windows-terminal-tweaker

After running npm run release from the renderer folder , it builds the app in the renderer/dist directory.

The dist/TerminalTweaker directory has all the built files along with the .exe file.

After this I use the electron-windows-store to be able to make my app publish ready. Here is my script for this :

const convertToWindowsStore = require('electron-windows-store')

convertToWindowsStore({
   containerVirtualization: false,
   inputDirectory: 'dist/TerminalTweaker',
   outputDirectory: 'output',
   packageVersion: '1.0.0.0',
   packageName: 'terminalTweaker',
   identityName : '<secretId>' , 
   familyName : '<secretString>' ,
   publisherDisplayName : "Natesh M Bhat" , 
   packageDisplayName: 'Terminal Tweaker',
   packageDescription: 'Tweak your windows terminal to heart's content with this app using its beautiful interface to configure everything about the terminal.',
   packageExecutable: 'dist/TerminalTweaker/Terminal Tweaker.exe',
   publisher: 'CN=<secretString>',
   windowsKit: 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64',
   finalSay: function () {
     return new Promise((resolve, reject) => resolve())
   }
})

Now once I get the terminalTweaker.appx , I uploaded this package in windows store app dashboard.

When I submit submission , its getting rejected showing the following error. How do I fix this ?

App Policies: 10.1.1 Icon

Notes To Developer

The available app icons include a default icon. Icons must uniquely represent apps so users associate icons with the appropriate apps and do not confuse one app for another. For information about icons and tiles in Windows apps, see Application Icons and Logos, or for 3D icons for Mixed Reality apps, see
3D app launcher design guidance.


Get this bounty!!!

#StackBounty: #javascript #reactjs #firebase #google-cloud-firestore How to use firebase auth and Cloud Firestore from different compon…

Bounty: 50

I am trying to use firebase in my React project to provide the auth and database functionalities.

In my App.js I have

import app from "firebase/app";
import "firebase/auth";
app.initializeApp(firebaseConfig);

In my other components called <Component /> rendered by App.js I have this to initialize the database

import app from "firebase/app";
import "firebase/firestore";
const db = app.firestore();

However this time I got this error

Uncaught FirebaseError: Firebase: No Firebase App '[DEFAULT]' has been created - call Firebase App.initializeApp() (app/no-app).

So I tried to put app.initializeApp(firebaseConfig); in this component too but I got a new error again to tell me I instantiated twice.

Uncaught FirebaseError: Firebase: Firebase App named '[DEFAULT]' already exists (app/duplicate-app).

So one workaround I came up with is to create a context at App.js and right after app.initializeApp(firebaseConfig); I created the database by const db = app.firestore(); and pass the value to the context and let the <Component /> to consume. However I don’t know if this is a good solution or not.

My question is different from How to check if a Firebase App is already initialized on Android for one reason. I am not trying to connect to a second Firebase App as it was for that question. There is only one Firebase App for my entire project, to provide two services: auth and database.

I tried the solution from that question to use in <Component />

if (!app.apps.length) {
  app.initializeApp(firebaseConfig);
}

const db = app.firestore();

but it didn’t work it still gives me Uncaught FirebaseError: Firebase: Firebase App named '[DEFAULT]' already exists (app/duplicate-app). error


Get this bounty!!!

#StackBounty: #javascript #html #css #reactjs #redux each attachment I need to attach pdf or word or jpg icon

Bounty: 50

  • in driveFiles I am getting multiple file names.
    – for each attachment I need to attach pdf or word or jpg icon
    – so I used substr and lastIndexOf got the file formats.
    – now using if conditions I am able to disable icon for one files.
    – if I test for more than one files, its not checking for second if.
    – I think the problem is due to the return statement in first if.
    – can you tell me how to fix it for multiple files.
    – providing my code snippet below.

        <!-- language-all: lang-or-tag-here -->
    
    
                      {this.props.driveFiles.length > 0
                        ? this.props.driveFiles.map(_driveFileKey => {
                            var driveFormat = _driveFileKey.name.substr(
                              _driveFileKey.name.lastIndexOf(".") + 1
                            );
                            console.log("filename--->", driveFormat);
                            if (driveFormat === "pdf") {
                              return (
                                
    {" "} {_driveFileKey.name}
    ); } else if (driveFormat === "doc") { return (
    {" "} {_driveFileKey.name}
    ); } else if (driveFormat === "jpg") { return (
    {" "} {_driveFileKey.name}
    ); } //return
    {_driveFileKey.name}
    ; }) : ""}


Get this bounty!!!

#StackBounty: #javascript #reactjs getDerivedStateFromProps, change of state under the influence of changing props

Bounty: 50

I click Item -> I get data from url:https: // app / api / v1 / asset / $ {id}. The data is saved in loadItemId. I am moving loadItemId from the component Items to the component Details, then to the component AnotherItem.
Each time I click Item the props loadItemId changes in the getDerivedStateFromProps method. Problem: I’ll click Element D -> I see in console.log ‘true’, then I’ll click Element E –> It display in console.log true andfalse simultaneously, and it should display only false.

Trying to create a ternary operator {this.state.itemX ['completed'] ? this.start () : ''}. If {this.state.itemX ['completed'] call the function this.start ()

Code here: stackblitz

Picture: https://imgur.com/a/OBxMKCd

Items

class Items extends Component {
  constructor (props) {
    super(props);
    this.state = {   
      itemId: null,  
      loadItemId: ''
    }
  }

  selectItem = (id) => {
    this.setState({
      itemId: id
    })

        this.load(id);
  }

    load = (id) => {

        axios.get
            axios({
                    url: `https://app/api/v1/asset/${id}`,
                    method: "GET",
                    headers: {
                        'Authorization': `Bearer ${token}`           
                    }
            })
            .then(response => {
                    this.setState({
                            loadItemId: response.data
                    });
            })
            .catch(error => {
                    console.log(error);
            })
}

  render () {
    return (
            
) }

Item

class Item extends Component {
  render () {

    return (
      
this.props.selectItem(item.id}>
) } }

Details

class Details extends Component {
    constructor() {
        super();
    }

  render () {
    return (
            
) } }

AnotherItem

class AnotherItem extends Component {


  constructor() {
    super();

    this.state = {
      itemX: ''
    };
  }


  static getDerivedStateFromProps(nextProps, prevState) {
    if(nextProps.loadItemId !== prevState.loadItemId) {
      return { itemX: nextProps.loadItemId }
    }

  render () {
      console.log(this.state.itemX ? this.state.itemX['completed'] : '');

    {/*if this.state.loadX['completed'] === true, call function this.start()*/ }
    return (
            <button /*{this.state.loadX['completed'] ? this.start() : ''}*/ onClick={this.start}>
                Start
            </button>      
    );
  }
}


Get this bounty!!!

#StackBounty: #javascript #reactjs #datetime #momentjs Difference between dates, rounded result to nearest minute

Bounty: 50

The difference between dates wants to round to the nearest minute.
Round date1,date2 down or up. The returned result is already rounded up to the full minute. I can modify date1,date2. Do not modify the result already returned

date2- date1

Code here: https://stackblitz.com/edit/react-azau4g

Example:

First step

this.state = {
  date1: "2019-06-29 21:25:38+00",
  date2: "2019-06-29T21:25:40.000+00:00"
}

round = (item) => {
  var m = moment(item);

  var roundUp = (m.second() || m.millisecond() ? m.add(1, 'minute').startOf('minute') : m.startOf('minute')).toISOString();
  return roundUp;
}

differentTime = {
    date1: this.state.date1.toISOString(),  
    date2: this.round(this.state.date2)   //return "2019-06-29T21:26:00.000+00:00"
}

Second step

Expected effect:

data2data1 = 1 min


Example 2

 this.state = {
      date1: "2019-06-29 21:25:01+00",
      date2: "2019-06-29T21:27:20.000+00:00"
    }



 differentTime2 = {
        date1: this.state.date1.toISOString(), 
        date2: this.round(this.state.date2)   //return "2019-06-29T21:28:00.000+00:00"
    }

Expecting effect:

date2date1 = 3 min


Get this bounty!!!

#StackBounty: #reactjs #enzyme #react-router-v4 #react-hooks #react-context Enzyme errors with React Context and Hooks API

Bounty: 50

I’ve created this RootContext to handle authentication for my small React Hooks app. Everything works as expected except for getting weird errors using Enzyme’s shallow and mount.

I’m trying to test it like this:

const wrapper = mount(<Login />)

Index:

import RootContext from './RootContext'

function Root() {
  return (
    <RootContext>
      <App />
    </RootContext>
  )
}

ReactDOM.render(<Root/>, document.getElementById('root'));

RootContext:

import React, { useEffect, useState } from 'react'
export const RootContext = React.createContext()

export default ({ children }) => {
  const auth = window.localStorage.getItem('authenticated') || 'false'
  const cred = window.localStorage.getItem('credentials') || null
  const [authenticated, setAuthenticated] = useState(auth)
  const [credentials, setCredentials] = useState(cred)

  useEffect(
    () => {
      window.localStorage.setItem('authenticated', authenticated)
      window.localStorage.setItem('credentials', credentials)
    },
    [authenticated, credentials]
  )

  const defaultContext = {
    authenticated,
    setAuthenticated,
    credentials,
    setCredentials 
  }

  return (
    <RootContext.Provider value={defaultContext}>
      {children}
    </RootContext.Provider>
  )
}

Login, Logout and Register all use the useAuthenticate hook that causes this issue. The BmiForm component works fine.

import AuthenticatedRoute from './AuthenticatedRoute'

export default function App() {

  return (
    <Router>
      <Header />
      <Switch>
        <Container>
          <Row>
            <Col md={{ span: 4, offset: 4 }}>
              <AuthenticatedRoute exact path="/" component={BmiForm} />
              <Route exact path="/login" component={ Login } />
              <Route exact path="/logout" component={ Logout } />
              <Route exact path="/register" component={ Register } />
            </Col>
          </Row>
        </Container>
      </Switch>
    </Router>
  )
}

The useAuthenticate hook that’s causing the issue:

import useReactRouter from 'use-react-router';
import { RootContext } from './../RootContext'

export default function useAuthenticate() {
  const { history } = useReactRouter()
  const {
    authenticated,
    setAuthenticated,
    credentials,
    setCredentials
  } = useContext(RootContext);

Adding the useAuthenticate hook to the BmiForm, causes its test to fail the same way.

import useAuthenticate from './custom/useAuthenticate'

export default function BmiForm(props) {
  const { credentials, setAuthenticated } = useAuthenticate()

First error I get:

    TypeError: Cannot read property 'authenticated' of undefined

       5 | export default function useAuthenticate() {
       6 |   const {
    >  7 |     authenticated,
         |     ^
       8 |     setAuthenticated,
       9 |     credentials,
      10 |     setCredentials

Second error with stacktrace:

   use-react-router may only be used within a react-router context.

      4 | 
      5 | export default function useAuthenticate() {
    > 6 |   const { history } = useReactRouter()
        |                       ^
      7 |   const {
      8 |     authenticated,
      9 |     setAuthenticated,

      at useRouter (node_modules/use-react-router/src/use-react-router.ts:20:11)
      at useAuthenticate (src/custom/useAuthenticate.js:6:23)
      at BmiForm (src/BmiForm.js:15:45)
      at renderWithHooks (node_modules/react-dom/cjs/react-dom.development.js:12839:18)
      at mountIndeterminateComponent (node_modules/react-dom/cjs/react-dom.development.js:14816:13)
      at beginWork (node_modules/react-dom/cjs/react-dom.development.js:15421:16)
      at performUnitOfWork (node_modules/react-dom/cjs/react-dom.development.js:19108:12)
      at workLoop (node_modules/react-dom/cjs/react-dom.development.js:19148:24)
      at renderRoot (node_modules/react-dom/cjs/react-dom.development.js:19231:7)
      at performWorkOnRoot (node_modules/react-dom/cjs/react-dom.development.js:20138:7)
      at performWork (node_modules/react-dom/cjs/react-dom.development.js:20050:7)
      at performSyncWork (node_modules/react-dom/cjs/react-dom.development.js:20024:3)
      at requestWork (node_modules/react-dom/cjs/react-dom.development.js:19893:5)
      at scheduleWork (node_modules/react-dom/cjs/react-dom.development.js:19707:5)
      at scheduleRootUpdate (node_modules/react-dom/cjs/react-dom.development.js:20368:3)
      at updateContainerAtExpirationTime (node_modules/react-dom/cjs/react-dom.development.js:20396:10)
      at updateContainer (node_modules/react-dom/cjs/react-dom.development.js:20453:10)
      at ReactRoot.Object.<anonymous>.ReactRoot.render (node_modules/react-dom/cjs/react-dom.development.js:20749:3)
      at node_modules/react-dom/cjs/react-dom.development.js:20886:14
      at unbatchedUpdates (node_modules/react-dom/cjs/react-dom.development.js:20255:10)
      at legacyRenderSubtreeIntoContainer (node_modules/react-dom/cjs/react-dom.development.js:20882:5)
      at Object.render (node_modules/react-dom/cjs/react-dom.development.js:20951:12)
      at Object.render (node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:382:114)
      at new ReactWrapper (node_modules/enzyme/build/ReactWrapper.js:134:16)
      at mount (node_modules/enzyme/build/mount.js:21:10)
      at test (src/test/bmi_calculator.step.test.js:22:21)
      at defineScenarioFunction (node_modules/jest-cucumber/src/feature-definition-creation.ts:155:9)
      at test (src/test/bmi_calculator.step.test.js:20:3)
      at Suite.<anonymous> (node_modules/jest-cucumber/src/feature-definition-creation.ts:279:9)
      at defineFeature (node_modules/jest-cucumber/src/feature-definition-creation.ts:278:5)
      at Object.<anonymous> (src/test/bmi_calculator.step.test.js:19:1)

I’ve tried various solutions involving Enzyme’s setContext. But not sure whether this is related to the Context or react-router or both.


Get this bounty!!!

#StackBounty: #javascript #wordpress #reactjs #wordpress-gutenberg #gutenberg-blocks Gutenberg editor scroll block into view

Bounty: 100

How can I scroll a newly inserted block into the view in the wordpress gutenberg editor?

I am creating the block with

const nextBlock = createBlock( 'core/paragraph' );
wp.data.dispatch( 'core/editor' ).insertBlock( nextBlock );
//scroll the block into the view

I have also seen that gutenberg uses the dom-scroll-into-view package like e.g. here.

Their documentation says:

var scrollIntoView = require('dom-scroll-into-view');
scrollIntoView(source,container,config);

but what are the parameters source, container, config in my case?


Get this bounty!!!

#StackBounty: #reactjs #material-ui Creating Tweet Display Box in ReactJS

Bounty: 200

I am using the following code to generate a Tweet input box which takes in text/video/image/emoji. And they can be in different combinations.

I am not sure how to generate a tweet display box which shows the final display containing text/image/emoji ? I understand I might need to put the different inputs in an array or some sort but what after that. My current code for display side is performing nothing and I am not sure where to go from here.

I am looking for display box to be of following form after a Submit Button:

enter image description here

Code components/EmojiPicker.js has:

import React, {useState} from 'react'
import ReactDOM from "react-dom";
import { Picker } from "emoji-mart";
import Button from "@material-ui/core/Button";

const EmojiPicker = ({ onSelect }) => {
    const [show, setShow] = useState(false);
    return (
      <>
        <Button
          onClick={() => setShow(oldState => !oldState)}
          style={{ width: "30px", height: "30px", borderRadius: "4px", border: "3px solid", display: "flex", alignItems: "center", justifyContent: "center",
            background: "transparent"}}>
          ej
        </Button>
        {ReactDOM.createPortal(
          show && <Picker onSelect={onSelect} />,
          document.body
        )}
      </>
    );
  };

  export default EmojiPicker

Code components/FileInput.js has:

import React, {useRef} from 'react'

const FileInput = ({ onChange, children }) => {
    const fileRef = useRef();
    const onPickFile = event => {
      onChange([...event.target.files]);
    };
    return (
      
fileRef.current.click()} > {children}
); }; export default FileInput

Code components/tweetboxImgInp.js as:

import React, {useState, useEffect} from 'react'


const ImgIcon = () => (
    <svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
      <path d="M0 0h24v24H0z" fill="none" />
      <path d="M14 13l4 5H6l4-4 1.79 1.78L14 13zm-6.01-2.99A2 2 0 0 0 8 6a2 2 0 0 0-.01 4.01zM22 5v14a3 3 0 0 1-3 2.99H5c-1.64 0-3-1.36-3-3V5c0-1.64 1.36-3 3-3h14c1.65 0 3 1.36 3 3zm-2.01 0a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h7v-.01h7a1 1 0 0 0 1-1V5z" />
    </svg>
  );

  export const Img = ({ file, onRemove, index }) => {
    const [fileUrl, setFileUrl] = useState(null);
    useEffect(() => {
      if (file) {
        setFileUrl(URL.createObjectURL(file));
      }
    }, [file]);

    return fileUrl ? (
      
pic
onRemove(index)} style={{ position: "absolute", right: 0, top: 0, width: "20px", height: "20px", borderRadius: "50%", background: "black", color: "white", display: "flex", alignItems: "center", justifyContent: "center" }} > x
</div> ) : null; }; export default ImgIcon

And App.js has:

import React, { useRef, useState } from "react";
import ImgIcon, {Img} from './components/tweetboxImgInp'
import EmojiPicker from './components/EmojiPicker'
import FileInput from './components/FileInput'
import "emoji-mart/css/emoji-mart.css";
import "./styles.css";

function App() {
  const [text, setText] = useState("");
  const [pics, setPics] = useState([]);
  const textAreaRef = useRef();
  const insertAtPos = value => {
    const { current: taRef } = textAreaRef;
    let startPos = taRef.selectionStart;
    let endPos = taRef.selectionEnd;
    taRef.value =
      taRef.value.substring(0, startPos) +
      value.native +
      taRef.value.substring(endPos, taRef.value.length);
  };
  return (