File input click not opening dialog in Microsoft Edge despite successful API calls

Problem Summary

File input <input type="file"> click events are not opening the file selection dialog in Microsoft Edge, despite the same code working perfectly in Safari and other browsers. Drag-and-drop functionality works fine in Edge.

Environment

  • Browser: Microsoft Edge (latest version)
  • OS: macOS
  • Framework: React 18 with Next.js
  • Context: Secure context (HTTPS/localhost)

What Works

Drag and drop file selection works perfectly in Edge
Button click works perfectly in Safari and other browsers
All programmatic API calls return “success” but no dialog appears

What Doesn’t Work

Any form of programmatic file input triggering in Edge
File selection dialog never appears despite “successful” API calls

Code Example

const FileUploadComponent = () => {
  const fileInputRef = useRef<HTMLInputElement>(null);

  const handleClick = () => {
    const fileInput = fileInputRef.current;
    if (!fileInput) return;

    // All of these appear to "succeed" but no dialog opens in Edge:
    
    // Method 1: Direct click
    fileInput.click(); // Returns undefined, no error
    
    // Method 2: showPicker API
    if ('showPicker' in fileInput) {
      fileInput.showPicker(); // No error thrown, appears successful
    }
    
    // Method 3: Focus then click
    fileInput.focus(); // Element gets focused successfully
    fileInput.click(); // No error, no dialog
  };

  return (
    <div>
      <button onClick={handleClick}>Select File</button>
      <input
        ref={fileInputRef}
        type="file"
        style={{ display: 'none' }}
        onChange={(e) => console.log('File selected:', e.target.files)}
      />
    </div>
  );
};

Debug Information

When clicking the button in Edge, console shows:

✅ File input element found
✅ showPicker() called successfully  
✅ Element successfully focused
✅ click() called successfully
✅ userActivation: true (initially)
❌ No file dialog appears
❌ onChange never fires

Attempted Solutions

Tried ALL of these approaches with no success:

  1. Direct programmatic click: fileInput.click()
  2. Modern showPicker API: fileInput.showPicker()
  3. Focus then click: fileInput.focus(); fileInput.click()
  4. Mouse event dispatching: fileInput.dispatchEvent(new MouseEvent('click'))
  5. Label association: <label><input type="file"></label>
  6. Temporary visibility: Making element visible during click
  7. Invisible overlay: Positioning file input over button for direct user click
  8. Event timing: Immediate vs setTimeout approaches

Key Observations

  • User activation preserved: Click handlers are called synchronously from user events
  • No JavaScript errors: All API calls complete without throwing
  • Element state is correct: File input is connected, not disabled, properly focused
  • Security context is valid: window.isSecureContext === true
  • Works in other browsers: Identical code works in Safari, Chrome, Firefox

Question

What is Microsoft Edge specifically blocking that prevents file input dialogs from opening, even when using the modern showPicker() API and proper user activation?

Is there a specific Edge security policy, CSP header, or browser setting that could be interfering with file input functionality? Are there any Edge-specific workarounds for this issue?

How can I animate content using a cutout-style animation in JavaScript/CSS?

I’m working on a personal project where I want to animate webpage content using a cutout-style animation, inspired by effects seen in gaming YouTube intros or pop-up overlays in gameplay videos. I aim to use this style both in my YouTube video workflow and on a webpage, especially when revealing or transitioning in content like divs, images, or text blocks.

What I’m trying to achieve:
A visual effect where content slides, pops, or snaps into view, like a paper cutout or sticker being placed on screen.

The animation should feel dynamic and stylized, similar to effects used by content creators and streamers.

Ideally built using CSS animations or JavaScript, possibly combined with transitions, transforms, and shadows.

What I’ve tried:
So far, I’ve tried a basic CSS animation that scales and rotates content while fading it in. It gives a soft pop-in effect, which works, but it’s not as layered or “cartoon-like” as I’d like.

I want to push this further by adding:

Staggered timing for multiple elements

A bit of “impact” or bounce when elements land

Optional shadow flicks or highlights to enhance the illusion of motion

What I need help with:
Are there JavaScript libraries or animation frameworks (like GSAP or anime.js) that are great for this style of animation?

How can I reuse this effect for different elements or sections on a page?

Any tips on blending this with video editing tools like After Effects so that my web animations match my YouTube content (especially transitions and overlays)?

Bonus context:
This is part of a personal brand and content workflow I’m building for my YouTube channel and portfolio website. I’m aiming for a consistent animated theme across both platforms.

Thanks in advance! I’d love to hear any ideas or resources that could help bring this to life.

No error in catch block is but “TypeError: Object(…) is not a function” instead

Using vue 2 and a Lua back-end. I am testing my errors and would like to pas the custom error messages that I defined in user_ubject.lua to be passed to my front-end application. For some reason when the session is not valid, instead of my custom error messages, I get the following error in the Console in the front-end:

TypeError: Object(...) is not a function

Online user.actions.js: 77 which is:
console.log(error.toString())

All the logs from Lua are fine. The message gets passes correctly to respond_error

In my network tab I see the error 401, with in its response {"error":"No session token"}

But I can not get it in the catch block of isSessionValid in my user.actions.js

user_object.lua

local function respond_error(status, message)
    ngx.status = status
    ngx.say(cjson.encode({ error = message }))
    ngx.exit(status)
end

function BaseObject:IsValidSession()
    ngx.log(ngx.INFO, "Start IsValidSession")

    local ENDPOINT = "token/introspect"

    -- Get the refresh token and access token from cookies
    local ck = cookie:new()
    local refresh_token, refresh_err = ck:get("refresh_token")
    local access_token, access_err = ck:get("access_token")

    if not refresh_token then
        ngx.log(ngx.WARN, "Refresh token not found in cookie: " .. (refresh_err or "not present"))
        if not access_token then
            ngx.log(ngx.WARN, "Access token not found in cookie: " .. (access_err or "not present"))
        end
    end

    local token = refresh_token or access_token
    if not token then
        ngx.log(ngx.ERR, "IsValidSession: no token found in cookies")
        return respond_error(ngx.HTTP_UNAUTHORIZED, "No session token")
    end

    -- Prepare the POST data
    local post_data = ngx.encode_args({
        client_id = CLIENT_ID,
        client_secret = CLIENT_SECRET,
        token = token
    })

    -- Make the HTTP POST request to Keycloak
    local res, err = self:KeycloakHttpPost(post_data, ENDPOINT)
    if not res then
        ngx.log(ngx.ERR, "IsValidSession: unable to contact Kaycloak - " .. (err or "unknown error"))
        return respond_error(ngx.HTTP_BAD_GATEWAY, "Authentication server unavailable")
    end

    -- Handle the response
    ngx.log(ngx.INFO, "IsValidSession: Received validate response from Keycloak with status: " .. res.status)

    if res.status == 400 then
        return respond_error(ngx.HTTP_BAD_REQUEST, "Invalid session check")
    elseif res.status == 401 then
        return respond_error(ngx.ngx.HTTP_UNAUTHORIZED, "Unauthorized session")
    elseif res.status == 500 then
        return respond_error(ngx.HTTP_BAD_GATEWAY, "Authentication server error")
    elseif res.status ~= 200 then
        return respond_error(res.status, "Unexpected auth response")
    end

    local body = cjson.decode(res.body)
    ngx.log(ngx.INFO, "BODY: " .. cjson.encode(body))
    if not body then
        ngx.log(ngx.ERR, "IsValidSession: failed to decode JSON response")
        return false, "Invalid response format"
    end

    if body.active == true then
        ngx.log(ngx.INFO, "IsValidSession: session is active")
        return true, "Active session"
    else
        ngx.log(ngx.INFO, "IsValidSession: session is inactive or expired")
        return false, "Inactive session"
    end
end

api.lua

local function is_valid_session()
    return UserModel:IsValidSession()
end

r:match({
    POST = {
    ["/api/keycloak/session/validate"] = is_valid_session
...

user.actions.js

  isSessionValid ({ dispatch }) {
    return axios.post('/api/keycloak/session/validate')
      .then(() => {
        if (!refreshIntervalId) {
          dispatch('startAccesTokenRefreshLoop')
        }

        return axios.get('/api/keycloak/me', { withCredentials: true })
      })
      .then((response) => {
        dispatch('MessagesModule/addMessage', { text: 'Welcome back ' + response?.data?.username || 'User', color: 'info' }, { root: true })
        return dispatch('setUserData', { userData: response.data });
      })
      .catch((error) => {
        console.log(error.toString())
        if (refreshIntervalId) {
          clearInterval(refreshIntervalId);
          refreshIntervalId = null;
        }

        dispatch('clearUserData', {});
        return false;
      });
  },

I want to know what causes latency in audio elements on mobile [closed]

link : 941n.github.io/simpler

github-link: github.com/941n/simpler

This is my first time using this site and my English is not good so I used a translator. Please understand. I’m sorry.

I tried to implement the sampler function as a simple toy project. On the desktop, it works as I want. I don’t know if it’s right to say latency, but there is latency in the mobile (iOS & Android) environment. What is the reason for this, and what are the solutions or reference documents?

const pads = document.querySelectorAll('.pad');
const pausePad = document.querySelector('#pause-pad');

pads.forEach(pad => {
  if (pad.dataset.samplepath) {
    pad.innerHTML = `<audio src="${pad.dataset.samplepath}" preload="auto"></audio>`;
  }
  pad.addEventListener('click', sampleControl);
});

function sampleControl(e) {
  const pad = e.currentTarget;
  const sample = pad.querySelector('audio');
  const samples = document.querySelectorAll('audio');

  if (pad.id === 'pause-pad') {
    samples.forEach(sample => {
      sample.pause();
      sample.currentTime = 0; // Reset all samples to the beginning
    });

    return;
  }

  sample.pause();
  sample.currentTime = 0; // Reset to the beginning
  sample.play();
}
* {
  font-size: 10px;
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  border: 0;
  list-style: none;

  font-family: 'Roboto', sans-serif;
  text-transform: uppercase;

  user-select: none;
  -webkit-user-select: none;
}

body {
  display: grid;
  min-height: 80vh;

  align-content: center;
  justify-content: center;
  justify-items: center;

  background-color: rgb(140, 136, 134);
}

#sampler-name {
  margin: 0 0 2rem 0;
  width: fit-content;
}

#sampler-name span {
  font-family: 'Orbitron', sans-serif;
  font-size: 5rem;
  font-weight: 400;

  -webkit-text-stroke: 3px;
  paint-order: stroke fill;

  letter-spacing: 6px;

  border-bottom: 0.4rem solid;
}

#sampler-name #model {
  -webkit-text-fill-color: rgb(140, 136, 134);
}

#sampler-name #series {
  border-color: rgb(116, 0, 6);
}

#pads {
  display: grid;
  padding: 3rem;

  gap: 1rem;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(4, 1fr);

  border-radius: 1px;
  margin: auto;

  background-color: rgb(81, 80, 86);
}

.pad-wrap {
  display: flex;
  flex-direction: column;

  gap: 0.2rem;
}

.pad-info {
  display: flex;
  flex-direction: row;
  justify-content: space-between;

  padding-left: 0.4rem;
}

.pad-info .pad-command {
  color: rgb(151, 147, 154);
}

.pad {
  width: 6rem;
  height: 6rem;

  background-color: rgb(72, 63, 66);
  border-radius: 2px;
  border: 0.1rem solid;
}

.pad:hover,
.pad:active {
  background-color: rgb(92, 78, 83);
}

#pause-pad {
  background-color: rgb(116, 0, 6);
}
<link rel="icon" href="images/favicon.ico" type="image/x-icon" />
<link rel="apple-touch-icon" href="images/favicon.png" />
<link rel="apple-touch-icon" sizes="180x180" href="images/favicon.png" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Orbitron:[email protected]&family=Roboto:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="styles/base.css" />
<link rel="stylesheet" href="styles/sampler.css" />
<script src="scripts/sampleControl.js" defer></script>
<script src="scripts/sampler.js" defer></script>

<h2 id="sampler-name">
  <span id="model">MPC</span><span id="series">20</span>
</h2>

<ul id="pads">
  <li class="pad-wrap" id="pad-1">
    <div class="pad-info">
      <span class="pad-num">PAD 1</span><span class="pad-command">AB</span>
    </div>
    <div class="pad" data-samplepath="https://filesamples.com/samples/audio/m4a/sample4.m4a"></div>
  </li>
  <li class="pad-wrap" id="pad-2">
    <div class="pad-info">
      <span class="pad-num">PAD 2</span><span class="pad-command">CD</span>
    </div>
    <div class="pad" data-samplepath="https://filesamples.com/samples/audio/m4a/sample3.m4a"></div>
  </li>
  <li class="pad-wrap" id="pad-3">
    <div class="pad-info">
      <span class="pad-num">PAD 3</span><span class="pad-command">EF</span>
    </div>
    <div class="pad" data-samplepath="samples/third_note.m4a"></div>
  </li>
  <li class="pad-wrap" id="pad-4">
    <div class="pad-info">
      <span class="pad-num">PAD 4</span><span class="pad-command">GH</span>
    </div>
    <div class="pad" data-samplepath="samples/fourth_note.m4a"></div>
  </li>
  <li class="pad-wrap" id="pad-5">
    <div class="pad-info">
      <span class="pad-num">PAD 5</span><span class="pad-command">IJ</span>
    </div>
    <div class="pad" data-samplepath="samples/fiveth_note.m4a"></div>
  </li>
  <li class="pad-wrap" id="pad-6">
    <div class="pad-info">
      <span class="pad-num">PAD 6</span><span class="pad-command">KL</span>
    </div>
    <div class="pad" data-samplepath="samples/sixth_note.m4a"></div>
  </li>
  <li class="pad-wrap" id="pad-7">
    <div class="pad-info">
      <span class="pad-num">PAD 7</span><span class="pad-command">MN</span>
    </div>
    <div class="pad" data-samplepath="samples/seventh_note.m4a"></div>
  </li>
  <li class="pad-wrap" id="pad-8">
    <div class="pad-info">
      <span class="pad-num">PAD 8</span><span class="pad-command">OP</span>
    </div>
    <div class="pad" data-samplepath="samples/eighth_note.m4a"></div>
  </li>
  <li class="pad-wrap" id="pad-9">
    <div class="pad-info">
      <span class="pad-num">PAD 9</span><span class="pad-command">QR</span>
    </div>
    <div class="pad" data-samplepath="samples/start_intro.m4a"></div>
  </li>
  <li class="pad-wrap" id="pad-10">
    <div class="pad-info">
      <span class="pad-num">PAD 10</span><span class="pad-command">ST</span>
    </div>
    <div class="pad" data-samplepath="samples/look_at_you.wav"></div>
  </li>
  <li class="pad-wrap" id="pad-11">
    <div class="pad-info">
      <span class="pad-num">PAD 11</span><span class="pad-command">UV</span>
    </div>
    <div class="pad" data-samplepath="samples/ladies_and_gentlemen.wav"></div>
  </li>
  <li class="pad-wrap" id="pad-12">
    <div class="pad-info">
      <span class="pad-num">PAD 12</span><span class="pad-command">WX</span>
    </div>
    <div class="pad"></div>
  </li>
  <li class="pad-wrap" id="pad-13">
    <div class="pad-info">
      <span class="pad-num">PAD 13</span><span class="pad-command">YZ</span>
    </div>
    <div class="pad"></div>
  </li>
  <li class="pad-wrap" id="pad-14">
    <div class="pad-info">
      <span class="pad-num">PAD 14</span><span class="pad-command">&#35;&</span>
    </div>
    <div class="pad"></div>
  </li>
  <li class="pad-wrap" id="pad-15">
    <div class="pad-info">
      <span class="pad-num">PAD 15</span><span class="pad-command">- !</span>
    </div>
    <div class="pad"></div>
  </li>
  <li class="pad-wrap" id="pad-16">
    <div class="pad-info">
      <span class="pad-num">PAD 16</span><span class="pad-command">( )</span>
    </div>
    <div class="pad" id="pause-pad"></div>
  </li>
</ul>

How to exploit & in a Javascript generated SVG [closed]

Javascript. On running the whole code, it complains about:
Uncaught TypeError: prev.setAttribute is not a function, which triggers on the first encounter of setAttribute in the <defs> section

var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
const control_W = 550; //width of slider
const control_H = 300; //Height of slider
const arrowHeight = 10;
svg.setAttribute("id", "sliderControl");
svg.setAttribute("overflow", "visible");
svg.setAttribute("viewBox", "0 0 " + control_W + " " + control_H);
svg.setAttribute("width", control_W);
svg.setAttribute("height", control_H);
var svgNS = svg.namespaceURI;
//---------DEFS----------v
//create an add a <defs> section to svg
var defs = document.createElementNS(svgNS, 'defs');
svg.appendChild(defs);

//create and add a prototype svg 'prev' & 'next' arrow to the <defs> section
var prev = document.createAttributeNS(svgNS, 'path');
prev.setAttribute("d", "M 0,0 v -5 l -8,5 l 8,5 Z");
prev.setAttribute("fill", "#333333");
prev.setAttribute("stroke", "none");
prev.setAttribute("id", "prev");
defs.appendChild(prev);

//snipped the next arrow prototype
//---------DEFS----------^

//snipped

// create and set up the <use> svg section
const y_prev = document.createElementNS(svgNS, "use");
y_prev.setAttribute("x", "100");
y_prev.setAttribute("y", "100");
y_prev.setAttribute("id", "y_prev");
y_prev.setAttribute("fill", "silver");
y_prev.setAttribute("xlink:href", "#prev");
datePickerTitle.appendChild(y_prev);

//snipped next arrow <use> clause

tailwindcss 4.1.8 hard to change style with class tailwind [closed]

Anyone can tell me why when I try to change style of the elements html using tailwindcss 4.1.8 doesn’t change at all even I call the file output and install it via CLI correctly but when I change the style the elements based on code in output.css it works??

I hope it works when everytime I try to change style with the others name class of tailwindcss Docs not only based on output file tailwindcss

How to customize the CompositionEvent UI in JavaScript for IME keyboard logic on various browsers?

I just encountered What is JavaScript’s CompositionEvent? Please give examples From the little images/videos available on the topic, and given that I only ever really use a English/Latin keyboard on Chrome desktop or Safari iOS, my exposure to things like Chinese/Pinyin IME editors is limited.

First off, how can I test this on say Chinese using standard Pinyin input methods, or Japanese or Korean, for example?

Typing into the example box here for Spanish ´ e = é (Mac OPT+e then e) gives logs:

compositionstart: 
compositionupdate: ´
compositionupdate: é
compositionend: é

Working with ClaudeAI for a prototype using TipTap editor system, I end up with this, relevant portion of which is this:

const editor = useEditor({
  extensions: [
    StarterKit,
    Placeholder.configure({
      placeholder: 'Start typing... IME input is supported (中文, 日本語, 한국어, etc.)'
    })
  ],
  content: '',
  onUpdate: ({ editor }) => {
    setEditorContent(editor.getHTML());
  },
  editorProps: {
    attributes: {
      class: 'prose prose-sm sm:prose lg:prose-lg xl:prose-2xl mx-auto focus:outline-none min-h-[300px] p-4',
      spellcheck: 'false'
    },
    handleDOMEvents: {
      // Handle composition start (IME input begins)
      compositionstart: (view, event) => {
        const selection = view.state.selection;
        setImeState(prev => ({
          ...prev,
          isComposing: true,
          compositionStart: selection.from,
          compositionEnd: selection.to,
          compositionText: ''
        }));
        return false;
      },
      
      // Handle composition update (IME input changes)
      compositionupdate: (view, event) => {
        const compositionEvent = event as CompositionEvent;
        setImeState(prev => ({
          ...prev,
          compositionText: compositionEvent.data || ''
        }));
        return false;
      },
      
      // Handle composition end (IME input confirmed)
      compositionend: (view, event) => {
        const compositionEvent = event as CompositionEvent;
        setImeState(prev => ({
          ...prev,
          isComposing: false,
          compositionText: '',
          compositionStart: 0,
          compositionEnd: 0
        }));
        
        // Ensure the final composed text is properly inserted
        if (compositionEvent.data) {
          const { state, dispatch } = view;
          const { from, to } = state.selection;
          const tr = state.tr.insertText(compositionEvent.data, from, to);
          dispatch(tr);
        }
        
        return false;
      },
      
      // Handle input events for better IME support
      input: (view, event) => {
        // Let Tiptap handle regular input events
        // This ensures compatibility with IME composition
        return false;
      },
      
      // Handle keydown for special IME cases
      keydown: (view, event) => {
        // Don't interfere with IME composition
        if (imeState.isComposing) {
          // Allow certain keys during composition
          const allowedKeys = ['Escape', 'Tab', 'Enter'];
          if (!allowedKeys.includes(event.key)) {
            return false;
          }
        }
        return false;
      }
    }
  }
});

So it seems like these hooks will be called when some sort of native keyboard input tool writes to the browser on desktop or mobile/phone/etc.. Is that how it works? Like do you have to install an external keyboard tool to type in Chinese/Pinyin IME, on iPhone or Desktop Chrome? If so, (tangent but) I’d like to know where to find one, as I’m confused how to get started testing this.

The main question is, what can I customize with the IME UI?

I am thinking for a fantasy language like the one I’ve made here which uses a code editor in the browser, and when you type an English word then press tab, it converts it into the native word (which also uses Latin script, but theoretically it could use a different script).

So how would I properly go about building a sort of IME for a custom language, that works in the browser and phone in the normal places?

Just looking for high levels of:

  1. What are my options of how to play with IME for Chinese or a custom language?
  2. What is possible to customize (UI-wise, in browser Desktop, and iOS Safari)?
  3. What is not possible to customize?
  4. Should I just be using what’s there, or how much of the wheel do I need to reinvent basically?

java.lang.UnsatisfiedLinkError: could find DSO to load: libreactnativejni.so

So I am trying since days to get my react native app to work on android. I upgraded the app from 65.3 to 79.1 step by step according to the react native upgrade helper.

So now my app builds but crashes immediately after app start. Then I am logging the crash with adb logcat. In the logs I found the error:

java.lang.UnsatisfiedLinkError: could find DSO to load: libreactnativejni.so

So I started my journey to find the root cause and to fix it:

I have found the question already here on SO.
Tried all the solutions, nothing worked.
Then I have found this blog post.

I the most important paragraph:

It turns out that Android isn’t able to load 32- and 64-bit native libraries concurrently. This becomes an issue if you have at least one dependency with extensions compiled with ARM64 support and another that only supports ARM32. The system will detect the ARM64 dependency, load it, and then refuse to load the ARM32-only library, likely causing your application to crash.

He mentiones a solution there to to simply exclude all 64-bit binaries from your APK.

But when I do that I get the following error on the device:

This app isn’t compatible with the latest Android version. Check for an update or contact the app developer.

So this is no solution since I need to the dependencies in 64bit, otherwise the app does not open on ARM64 android devices or emulators.

I also found this SO answer. There it is mentioned that it is a known issue for react native since 2 years.

Now I am thinking to kick-out all ARM32 packages to have consistent dependencies for ARM64.

I found out that those packages are using ARM64:

  • /react-native/ReactAndroid/
  • /react-native/ReactCommon/
  • /react-native/React/Fabric/AppleEventBeat.cpp
  • /react-native-webview/
  • /@react-native-picker/
  • /react-native-screenguard/
  • /react-native-tts/
  • /react-native-safe-area-context/
  • /react-native-video/
  • /@react-native-community/netinfo/
  • /@react-native-community/netinfo/
  • /react-native-share/
  • /react-native-linear-gradient/
  • /react-native-screens/
  • /react-native-svg/
  • /react-native-gesture-handler/
  • /@react-native-async-storage/

I achieved this with running this command in the terminal: find . -type f ( -name "*.cpp" -o -name "*.cc" -o -name "*.cxx" -o -name "*.c++" )
Which finds all c++ files in packages. And c++ files are part of ARM64 packages.

So I am wondering how should I proceed.

Should I kick out all ARM32 dependencies and if so how can I achieve that.

Should I upgrade all dependencies and swap those out which are still on ARM32?

Am I on the right track?

This is the complete error message:

06-05 08:52:58.171 16349 16349 E AndroidRuntime: Process: com.client.sagly032721, PID: 16349
06-05 08:52:58.171 16349 16349 E AndroidRuntime: java.lang.UnsatisfiedLinkError: dlopen failed: library "libreact_featureflagsjni.so" not found
06-05 08:52:58.171 16349 16349 E AndroidRuntime:        at java.lang.Runtime.loadLibrary0(Runtime.java:1082)
06-05 08:52:58.171 16349 16349 E AndroidRuntime:        at java.lang.Runtime.loadLibrary0(Runtime.java:1003)
06-05 08:52:58.171 16349 16349 E AndroidRuntime:        at java.lang.System.loadLibrary(System.java:1661)
06-05 08:52:58.171 16349 16349 E AndroidRuntime:        at com.facebook.soloader.nativeloader.SystemDelegate.loadLibrary(SystemDelegate.java:24)
06-05 08:52:58.171 16349 16349 E AndroidRuntime:        at com.facebook.soloader.nativeloader.NativeLoader.loadLibrary(NativeLoader.java:52)
06-05 08:52:58.171 16349 16349 E AndroidRuntime:        at com.facebook.soloader.nativeloader.NativeLoader.loadLibrary(NativeLoader.java:30)
06-05 08:52:58.171 16349 16349 E AndroidRuntime:        at com.facebook.soloader.SoLoader.loadLibrary(SoLoader.java:805)
06-05 08:52:58.171 16349 16349 E AndroidRuntime:        at com.facebook.react.internal.featureflags.ReactNativeFeatureFlagsCxxInterop.<clinit>(ReactNativeFeatureFlagsCxxInterop.kt:28)
06-05 08:52:58.171 16349 16349 E AndroidRuntime:        at com.facebook.react.internal.featureflags.ReactNativeFeatureFlagsCxxAccessor.override(ReactNativeFeatureFlagsCxxAccessor.kt:475)
06-05 08:52:58.171 16349 16349 E AndroidRuntime:        at com.facebook.react.internal.featureflags.ReactNativeFeatureFlags.override(ReactNativeFeatureFlags.kt:316)
06-05 08:52:58.171 16349 16349 E AndroidRuntime:        at com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load(DefaultNewArchitectureEntryPoint.kt:57)
06-05 08:52:58.171 16349 16349 E AndroidRuntime:        at com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load$default(DefaultNewArchitectureEntryPoint.kt:35)
06-05 08:52:58.171 16349 16349 E AndroidRuntime:        at com.client.sagly032721.MainApplication.onCreate(MainApplication.kt:80)
06-05 08:52:58.171 16349 16349 E AndroidRuntime:        at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1316)
06-05 08:52:58.171 16349 16349 E AndroidRuntime:        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6998)
06-05 08:52:58.171 16349 16349 E AndroidRuntime:        at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0)
06-05 08:52:58.171 16349 16349 E AndroidRuntime:        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2236)
06-05 08:52:58.171 16349 16349 E AndroidRuntime:        at android.os.Handler.dispatchMessage(Handler.java:106)
06-05 08:52:58.171 16349 16349 E AndroidRuntime:        at android.os.Looper.loopOnce(Looper.java:205)
06-05 08:52:58.171 16349 16349 E AndroidRuntime:        at android.os.Looper.loop(Looper.java:294)
06-05 08:52:58.171 16349 16349 E AndroidRuntime:        at android.app.ActivityThread.main(ActivityThread.java:8177)
06-05 08:52:58.171 16349 16349 E AndroidRuntime:        at java.lang.reflect.Method.invoke(Native Method)
06-05 08:52:58.171 16349 16349 E AndroidRuntime:        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
06-05 08:52:58.171 16349 16349 E AndroidRuntime:        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)

Thank you for any help in advance. I am really stuck on this issue :/

How to access handle inside export const javascript [closed]

export const accelerometerInterop = {

    handle: function (event) {exports.Microsoft.Maui.Devices.Sensors.AccelerometerImplementation.OnReadingChanged(
            event.accelerationIncludingGravity.x || 0,
            event.accelerationIncludingGravity.y || 0,
            event.accelerationIncludingGravity.z || 0
        );
    },

    startListening: function () {
        if (window.DeviceOrientationEvent) {
            window.addEventListener("devicemotion", this.handle);
        }
    },

    stopListening: function () {
        window.removeEventListener("devicemotion", this.handle);
    }
};

I am calling it from c# using JSImport

internal partial class AccelerometerImplementation : AccelerometerImplementationBase
{
    [JSImport("accelerometerInterop.startListening", "essentials")]
    public static partial void StartListening();

    [JSImport("accelerometerInterop.stopListening", "essentials")]
    public static partial void StopListening();

    [JSExport]
    public static void OnReadingChanged(double x, double y, double z)
    {
        var implementation = Accelerometer.Default as AccelerometerImplementation;
        if (implementation == null)
            return; 
        if (!implementation.IsMonitoring)
            return;

        implementation.OnChanged(new AccelerometerChangedEventArgs(new AccelerometerData(x, y, z)));
    }

    public override bool IsSupported => true;

    protected override void PlatformStart(SensorSpeed sensorSpeed)
    {
        StartListening();
    }

    protected override void PlatformStop()
    {
        StopListening();
    }
}

It’s seems handle is not find, following error Uncaught ManagedError ManagedError: [object Object]
Error
at Jn (c:UserscedrisourcereposAvaloniaApplication1AvaloniaApplication1.Browserwwwroot_frameworkhttps:raw.githubusercontent.comdotnetruntimeefd5742bb5dd1677fbbbeb277bcfb5c9025548e5srcmonowasmruntimemarshal-to-js.ts:349:18)
at kr (c:UserscedrisourcereposAvaloniaApplication1AvaloniaApplication1.Browserwwwroot_frameworkhttps:raw.githubusercontent.comdotnetruntimeefd5742bb5dd1677fbbbeb277bcfb5c9025548e5srcmonowasmruntimeinvoke-cs.ts:277:19)
at (c:UserscedrisourcereposAvaloniaApplication1AvaloniaApplication1.Browserwwwroot_frameworkhttps:raw.githubusercontent.comdotnetruntimeefd5742bb5dd1677fbbbeb277bcfb5c9025548e5srcmonowasmruntimeinvoke-cs.ts:247:13)
at i (c:UserscedrisourcereposAvaloniaApplication1AvaloniaApplication1.Browserwwwrootwebappmodulesavaloniainput.ts:191:35)

Symfony EasyAdmin: How to embed and correctly display YouTube iframe inside a CollectionField?

I’m working on a Symfony project using EasyAdmin. I have a Page entity that contains a collection of Step entities. Each Step has a field called intro where I want to store and display a YouTube iframe embed code.

In my EasyAdmin CRUD controller, I use this configuration:

yield CollectionField::new('steps', 'Steps')
    ->setEntryType(IntroStepType::class)
    ->allowAdd()
    ->allowDelete()
    ->renderExpanded()
    ->addJsFiles(Asset::fromEasyAdminAssetPackage('field-text-editor.js')->onlyOnForms())
    ->addCssFiles(Asset::fromEasyAdminAssetPackage('field-text-editor.css')->onlyOnForms());

And my custom form type for ‘steps’ looks like this:

class IntroStepType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('title', TextType::class, [
                'label' => 'Title',
            ])
            ->add('element', TextType::class, [
                'label' => 'Element',
            ])
            ->add('intro', TextEditorType::class, [
                'label' => 'Instructions',
            ]);
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => Step::class,
        ]);
    }
}

Problem:

I can enter YouTube iframe embed code into the intro field via the text editor in easyadmin, but when viewing the detail page, the iframe is not rendered as HTML. Instead, it shows as plain text.

This is my Stimulus controller where i load the data in:

import { Controller } from '@hotwired/stimulus';
import introJs from 'intro.js';
import '../vendor/intro.js/introjs.css';

export default class extends Controller {
    async connect() {
        this.intro = introJs();

        this.baseOptions = {
            showBullets: false,
            showPrevButton: true,
            nextLabel: 'Next',
            prevLabel: 'Previous',
        };

        this.intro.setOptions(this.baseOptions);

        const params = new URLSearchParams(window.location.search);

        if ('true' === params.get('tutorial')) {
            await this.startTutorial();
        }
    }

    async startTutorial() {
        const path = encodeURIComponent(window.location.pathname);

        try {
            const response = await fetch(`/tutorial?path=${path}`);

            if (!response.ok) {
                console.error('Error loading tutorial data:', response.status, response.statusText);

                return;
            }

            const data = await response.json();
            if (!data.steps?.length) return;

            const steps = data.steps.filter(step => !step.element || document.querySelector(step.element));
            if (steps.length === 0) return;

            const options = {
                ...this.baseOptions,
                steps,
                doneLabel: data.next ? 'Next' : 'Done',
            };

            this.intro.setOptions(options);

            this.intro.oncomplete(() => {
                if (data.next) {
                    const nextUrl = new URL(window.location.origin + data.next);

                    nextUrl.searchParams.set('tutorial', 'true');

                    window.location.href = nextUrl.toString();
                } else {
                    this.removeTutorialQueryParam();
                }
            });

            setTimeout(() => this.intro.start(), 100);
        } catch (error) {
            console.error('Network error:', error);
        }
    }

    removeTutorialQueryParam() {
        const url = new URL(window.location);

        url.searchParams.delete('tutorial');

        window.history.replaceState({}, document.title, url);
    }
}


Any advice or examples are much appreciated.

Extra characters on php soapclient request XML

Yet another problem with PHP soapclient, I hope someone can show me the correct way of doing this:

Here is a portion of the parameter array to keep things simple:

$params = array (
        'communication' =>
        [
            'user-configuration' =>
            [
                'ruleset' =>
                [
                    'rule' => 
                     [
                         '_' => '',
                         'id' => '999',
                         'conditions' =>
                         [
                            'rule1' => 'true',
                         ],
                         'actions' =>
                         [
                            'forward-to' =>
                             [
                                'target' => '123456'
                             ],
                         ],                         
                     ],                     
                ],
            ],
        ],    
); 

I call the soapclient as follows:

   $client = new SoapClient
            ($wsdl, 
            array(
                'location' => "http://$ip:8080/CAI3G1.2/services/CAI3G1.2",
                'uri'      => "http://$ip:8080/CAI3G1.2/services/CAI3G1.2",
                'exceptions' => true,
                'cache_wsdl' => WSDL_CACHE_NONE,   
                'connection_timeout' => 5,
                'trace'    => 1,
                'encoding'=>' UTF-8'
        ));    
    
    $header = new SoapHeader('http://schemas.ericsson.com/cai3g1.2/','SessionId',$sessionID,false);
    $client->__setSoapHeaders($header);      
   try {
      $response = $client->Set($params);
    } catch(Exception $e){
      if ($debug) print_r($e);
      return $e;
    }
return $response;

The XML generated has an extra unwanted part highlighted as follows:

                <ns2:communication>
                    <ns2:user-configuration>
                        <ns2:ruleset>
                            <ns2:rule id="999">
                                <ns2:id>999</ns2:id>
                                <ns2:conditions>
                                    <ns2:rule1>true</ns2:rule1>
                                </ns2:conditions>
                                <ns2:actions>
                                    <ns2:forward-to>
                                        <ns2:target>123456</ns2:target>
                                    </ns2:forward-to>
                                </ns2:actions>
                            </ns2:rule>
                        </ns2:ruleset>
                    </ns2:user-configuration>
                </ns2:communication>

the server doesnt like these extra line added on the request:

<ns2:id>999</ns2:id> 

if I put the same request on soapUI the request does not contain this extra values, it is as follows, which the server accepts:

            <ns2:communication>
                <ns2:user-configuration>
                    <ns2:ruleset>
                        <ns2:rule id="999">
                            <ns2:conditions>
                                <ns2:rule1>true</ns2:rule1>
                            </ns2:conditions>
                            <ns2:actions>
                                <ns2:forward-to>
                                    <ns2:target>123456</ns2:target>
                                </ns2:forward-to>
                            </ns2:actions>
                        </ns2:rule>
                    </ns2:ruleset>
                </ns2:user-configuration>
            </ns2:communication>

nginx configuration with dynamic root for subfolder

I’m trying to write an nginx configuration for a change in our application directory structure. I want to be able to support developers who are running both the old version and the new version for the next few years.

In the new version of the application the only real change is that the web accessible code has been moved to a public directory.

We have a range of PHP files which are accessed directly, and some which are accessed through a router, r.php. We also have some which are accessed via a javascript endpoint which minifies (and caches) but the files are accessed using URLs in the form http://example.com/oldsite/javascript.php/some/js/file.

Each instance of the application is within a directory, for example:

├── oldsite
│   ├── index.php
│   ├── javascript.php
│   ├── mod
│   │   └── book
│   │       └── index.php
│   └── r.php
└── newsite
    └── public
        ├── index.php
        ├── javascript.php
        ├── mod
        │   └── book
        │       └── index.php
        └── r.php

The oldsite is access at http://example.com/oldsite/ and the newsite at http://example.com/newsite/.

I’m trying (and failing) to write an nginx configuration that will automatically handle both the old and new sites correctly.

This is what I have so far:

set $root /srv/sites
index index.php;

set $site "";
if ($uri ~ /(?<site>[^/]+)(?<relpath>/?.*)) {
    set $site $site;
}

set $docroot "$root/$site";
if (-d "/$docroot/public") {
    set $docroot "$root/$site/public";
}

location ~ /(?<site>[^/]+)(?<relpath>/.*.php)(/?|$) {
    root $docroot;
    include /opt/homebrew/etc/nginx/blocks/php.conf;
}

location ~ ^/(?<site>[^/]+)/?$ {
    root $docroot;

    rewrite ^(.*)/?$ $1/index.php last;

    location ~ .php$ {
        include /opt/homebrew/etc/nginx/blocks/php.conf;
    }
}

location ~ ^/(?<site>[^/]+)/?(?<relpath>.*)$ {
    root $docroot;

    location ~ .php$ {
        include /opt/homebrew/etc/nginx/blocks/php.conf;
    }
    try_files /$relpath /$relpath/ /r.php;
}

My php.conf looks like this:

fastcgi_split_path_info ^(.+.php)(/.*)$;

# Save path_info before try_files resets it
set $path_info $fastcgi_path_info;

include fastcgi_params;
fastcgi_param PATH_INFO $path_info;
fastcgi_param SCRIPT_FILENAME $docroot$relpath;
fastcgi_param DOCUMENT_ROOT $docroot;
fastcgi_pass   127.0.0.1:9000;
fastcgi_index index.php;

What is working:

  • http://example.com/oldsite (returns /index.php)
  • http://example.com/oldsite/ (returns /index.php)
  • http://example.com/oldsite/index.php
  • http://example.com/oldsite/javascript.php/some/file
  • http://example.com/oldsite/mod/book/index.php
  • http://example.com/newsite (returns /index.php)
  • http://example.com/newsite/ (returns /index.php)
  • http://example.com/newsite/index.php
  • http://example.com/newsite/mod/book/index.php
  • http://example.com/newsite/javascript.php/some/file

What is not working:

  • http://example.com/oldsite/notfound (returns 404) — should use /r.php
  • http://example.com/oldsite/mod/book (returns 404) — should use /mod/book/index.php
  • http://example.com/oldsite/mod/book/ (returns 404) — should use /mod/book/index.php

Digging into the logs, the final location match is used (correctly) but the try_files directive is not working as I expect.

2025/06/05 09:00:22 [debug] 80884#0: *31 generic phase: 13
2025/06/05 09:00:22 [debug] 80884#0:*31 try files handler
2025/06/05 09:00:22 [debug] 80884#0: *31 http script var: "/srv/sites/newsite/public"
2025/06/05 09:00:22 [debug] 80884#0:*31 http script copy: "/"
2025/06/05 09:00:22 [debug] 80884#0: *31 http script var: "mod/book/"
2025/06/05 09:00:22 [debug] 80884#0:*31 trying to use file: "/mod/book/" "/srv/sites/newsite/public/mod/book/"
2025/06/05 09:00:22 [debug] 80884#0: *31 http script copy: "/"
2025/06/05 09:00:22 [debug] 80884#0:*31 http script var: "mod/book/"
2025/06/05 09:00:22 [debug] 80884#0: *31 trying to use dir: "/mod/book/" "/srv/sites/newsite/public/mod/book/"
2025/06/05 09:00:22 [debug] 80884#0:*31 try file uri: "/mod/book/"
2025/06/05 09:00:22 [debug] 80884#0: *31 generic phase: 14
2025/06/05 09:00:22 [debug] 80884#0:*31 content phase: 15
2025/06/05 09:00:22 [debug] 80884#0: *31 content phase: 16
2025/06/05 09:00:22 [debug] 80884#0:*31 http script var: "/srv/sites/newsite/public"
2025/06/05 09:00:22 [debug] 80884#0: *31 open index "/srv/sites/newsite/public/mod/book/index.php"
2025/06/05 09:00:22 [debug] 80884#0:*31 internal redirect: "/mod/book/index.php?"

I can see that it’s trying to use the directory, which it finds successfully, but then that turns into an internal redirect, which then gets processed from the top and the $site var is turned into mod, which doesn’t then exist.

Likewise with a fallback URL:

2025/06/05 07:00:29 [debug] 80884#0: *11 try files handler
2025/06/05 07:00:29 [debug] 80884#0: *11 http script var: "/srv/sites/newsite/public"
2025/06/05 07:00:29 [debug] 80884#0: *11 http script copy: "/"
2025/06/05 07:00:29 [debug] 80884#0: *11 http script var: "mod/book/notfound"
2025/06/05 07:00:29 [debug] 80884#0: *11 trying to use file: "/mod/book/notfound" "/srv/sites/newsite/public/mod/book/notfound"
2025/06/05 07:00:29 [debug] 80884#0: *11 http script copy: "/"
2025/06/05 07:00:29 [debug] 80884#0: *11 http script var: "mod/book/notfound"
2025/06/05 07:00:29 [debug] 80884#0: *11 trying to use dir: "/mod/book/notfound" "/srv/sites/newsite/public/mod/book/notfound"
2025/06/05 07:00:29 [debug] 80884#0: *11 trying to use file: "/r.php" "/srv/sites/newsite/public/r.php"
2025/06/05 07:00:29 [debug] 80884#0: *11 internal redirect: "/r.php?"

It’s trying and (correctly) failing to find the file, and then it (correctly) falls back to /r.php, which it does find… only to redirect in the same way.

I feel like there’s something really obvious that I’m missing. I have thought about using a series of if tests instead of if tests, but this feels wrong. Another option would be some kind of proxy to an internal server directive I guess?

Thanks