#Camera/Gallery event

1 messages · Page 1 of 1 (latest)

safe knot
#

I’ve implemented the camera and gallery functionality in my app. It works perfectly on iOS, but on Android it doesn’t seem to receive the event data — I only see a console log saying “API event dispatch,” and it doesn’t print the event response. My stack is Inertia Vue.

#

Camera/Gallery event

hasty quest
#

what version of nativephp/mobile?

safe knot
#

versions : * 1.12.0

#
// Composable para listeners nativos globales
import mitt from 'mitt';

let listenersMounted = false;
let cameraListener = null;
let galleryListener = null;

// EventBus global para comunicación entre listeners nativos y componentes
const eventBus = window.__NATIVE_EVENT_BUS__ = window.__NATIVE_EVENT_BUS__ || mitt();

export default function useNativeListeners() {
  if (typeof window === 'undefined' || !window.Native?.on) return;
  if (listenersMounted) return;

  // Listener cámara
  cameraListener = (data) => {
    console.log('cameraListener', data)
    eventBus.emit('NativeCameraPhoto', data);
  };
  window.Native.on('Native\\Mobile\\Events\\Camera\\PhotoTaken', cameraListener);

  // Listener galería
  galleryListener = (data) => {
    console.log('galleryListener', data)
    eventBus.emit('NativeGalleryMedia', data);
  };
  window.Native.on('Native\\Mobile\\Events\\Gallery\\MediaSelected', galleryListener);

  listenersMounted = true;
}
#
<script>
import axios from 'axios';
import mitt from 'mitt';

const eventBus = window.__NATIVE_EVENT_BUS__ = window.__NATIVE_EVENT_BUS__ || mitt();

export default {
    props: {
        class: { type: String, default: '' },
        multiple: false,
        identifier: { type: String, required: true },
        token: String,
    },
    data() {
        return {
            photos: [],
            loadingGallery: false,
        };
    },
    methods: {
        async openGallery() 
        {
            try 
            {
                this.loadingGallery = true;
                window.__ACTIVE_GALLERY_IDENTIFIER__ = this.identifier;
                await axios.get(route('nativephp.getFile',{ multiple: this.multiple}));
            }
            catch (error) 
            {
                console.error('Error abriendo galería:', error);
            }
            finally
            {
                this.loadingGallery = false;
            }
        },
        saveToS3(files)
        {
...
        },
        onGalleryMedia(data) 
        {
            if (data?.files?.length)
            {
                if (window.__ACTIVE_GALLERY_IDENTIFIER__ !== this.identifier) return;
                this.saveToS3(data.files);
            }
        },
    },
    mounted() 
    {
        eventBus.on('NativeGalleryMedia', this.onGalleryMedia);
    },
    beforeUnmount() 
    {
        eventBus.off('NativeGalleryMedia', this.onGalleryMedia);
    },
};
</script>

<template>
    <a 
        href="#!"
        :class="class"
        @click="openGallery"
        :disabled="loadingGallery"
    >
        <i class="fa-solid fa-images"></i> {{ loadingGallery ? 'Abriendo galería...' : 'Seleccionar foto' }}
    </a>
</template>
safe knot
#

@hasty quest This is my current code — the composable is mounted only once in my app.ts. Later, I use the respective component wherever I need it. However, inside the galleryListener function, the console log doesn’t execute. Everything works perfectly on iOS, but on Android, it only runs the default console log from native events, and it never reaches my galleryListener. The same issue happens with the camera.

hasty quest
#

try just Native.on instead of window.Native.on

safe knot
#

Thanks, testing it…

safe knot
#

@hasty quest im triying to use just Native.on but i got an error:

Uncaught (in promise) ReferenceError: Native is not defined

any other idea? 🙁

hasty quest
#

I will look into it

safe knot
#

thank you so much!! 🥲

safe knot
#

@hasty quest i fix it, idk if is the best practice but actually I add a timeout before mount the eventBus, and it works, now I have other issue related with a verification in backend with file_exists() I think it doesn´t work on android

safe knot
#

it´s me again, just to ask why sometimes I´ve got

"request_all": {
    "event": "Native\\Mobile\\Events\\Camera\\PhotoTaken",
    "payload": {
      "path": "/data/user/0/com.pacificcapital.crm/cache/captured.jpg"
    }
  },

and other times:

"request_all": {
    "filePath": "/data/user/0/com.pacificcapital.crm/cache/captured.jpg"
  },
hasty quest
#

what are the variables

#

meaning, is one on ios and one on android

#

is one in an event listener and one in js?

safe knot
#

no is same eventListener: in my listener i have this:

// Listener galería
        galleryListener = (data) => {
            eventBus.emit('NativeGalleryMedia', data);
        };
        window.Native.on('Native\\Mobile\\Events\\Gallery\\MediaSelected', galleryListener);

this data contains:

{
    "success": true,
    "files": [
      {
        "path": "/data/user/0/com.pacificcapital.crm/cache/gallery_selected_1762917662955",
        "mimeType": "image/jpeg",
        "extension": "jpg",
        "type": "image"
      }
    ],
    "count": 1
  }

after that i send it to my controller:

axios.post(route('app.upload.gallery'), 
                { files },
                {
                    headers: {
                        'Content-Type': 'application/json',
                        'Authorization': `Bearer ${this.token}`,
                    }
                }
            )

but when I catch this in my controller is different:

{
    "event": "Native\\Mobile\\Events\\Gallery\\MediaSelected",
    "payload": {
      "success": true,
      "files": [
        {
          "path": "/data/user/0/com.pacificcapital.crm/cache/gallery_selected_1762917662955",
          "mimeType": "image/jpeg",
          "extension": "jpg",
          "type": "image"
        }
      ],
      "count": 1
    }
  }