Camera and Geolocation

Calling Camera and Geolocation from Framework7 Views

The device lab of Device, UI and System Plugins tried each plugin on its own. In a real view a plugin call is just an async function inside a Framework7 572,986 component. The book page's Notes tab (Routable Tabs Configuration) gains two buttons: a photo of a page, and the place where the reader read it. The template gets two button-tonal links bound with @click, and two $h blocks rendered only once there is a place or a photo to show. The component imports the plugins like any other module, keeps the results in local variables and calls $update() to re-render (Router Component Files):

src/pages/book-notes.f7: the component scriptJavaScript
  import { Capacitor } from '@capacitor/core';
  import { Camera } from '@capacitor/camera';
  import { Geolocation } from '@capacitor/geolocation';
  export default (props, { $f7, $store, $onMounted, $update }) => {
    const book = $store.getters.books.value.find((b) => b.id === Number(props.id));
    let photo = '';
    let place = '';
    $onMounted(() => console.log(`notes tab mounted for book ${props.id}`));
    // Plugin calls reject with a message: show it as a Framework7 toast
    const attempt = (task) => task().catch((err) => {
      console.log(`notes: ${err.message}`);
      $f7.toast.show({ text: err.message, closeTimeout: 2500 });
    });
    const addPhoto = () => attempt(async () => {
      if (!Capacitor.isNativePlatform()) throw new Error('Page photos need the BookNest app');
      const shot = await Camera.takePhoto({ quality: 70, targetWidth: 1000 });
      photo = shot.webPath; // a WebView-safe URL for the file the camera saved
      $update();
    });
    const addPlace = () => attempt(async () => {
      const { coords } = await Geolocation.getCurrentPosition({ enableHighAccuracy: true });
      place = `${coords.latitude.toFixed(4)}, ${coords.longitude.toFixed(4)}`;
      console.log(`notes: read at ${place}`);
      $update();
    });
    return $render;
  };

Rejections, such as a denied permission or a cancelled camera, become a Framework7 toast instead of an unhandled promise. webPath is a https://localhost/_capacitor_file_/... URL the WebView can load directly (Camera); on the emulator it was .../cache/PIC_20260925_002205.jpg. And the camera button refuses in a browser, while the location button falls back to the plugin's web implementation, which wraps navigator.geolocation. The emulator needed enableHighAccuracy: true before its simulated GPS fix (adb emu geo fix) was used; without it the request timed out.