Firebase deploy error: Neither apiKey nor config.authenticator provided (using Stripe)

This is in the context of a firebase app using Stripe with firebase functions.

   "dependencies": {
    "stripe": "^17.2.0",
    "twitter-api-v2": "^1.18.0",
    "firebase-admin": "^12.4.0",
    "firebase-functions": "^6",
    "moment-timezone": "^0.5.45"
  },

All was working fine until I updated all packages to the version shown above.
Since then, when I deploy firebase functions (how come this error is not just a runtime error ??), I get error message:

Error: Neither apiKey nor config.authenticator provided
    at Stripe._setAuthenticator (C:UserswebkoDocumentsAppsAndWebsitesNoderobotfunctionsnode_modulesstripecjsstripe.core.js:166:23)
    at new Stripe (C:UserswebkoDocumentsAppsAndWebsitesNoderobotfunctionsnode_modulesstripecjsstripe.core.js:102:14)
    at Stripe (C:UserswebkoDocumentsAppsAndWebsitesNoderobotfunctionsnode_modulesstripecjsstripe.core.js:58:20)
    at Object.<anonymous> (C:UserswebkoDocumentsAppsAndWebsitesNoderobotfunctionsindex.js:37:33)

The line in question is this one:

const stripe = require('stripe')(process.env.STRIPE_SECRET);

Since the update, it refuses ‘process.env.STRIPE_SECRET’. But works fine when I hardcode the test key as string.

The secret IS set in the environement, and when I run:

 firebase functions:secrets:access STRIPE_SECRET

It correctly shows the secret.

So why passing the secret as ‘process.env.STRIPE_SECRET’ is now a problem ?

Not able to pass row id to the page item

I am having a interactive grid in oracle apex. One of the column is a pop up lov type. when the user changes the value in this column, it has to open a page and pass the row id of that particular cell. I tried the below JavaScript.

 var ig = apex.region("your_grid_region_static_id").widget().interactiveGrid("getViews", "grid").model;
var selectedRecords = apex.region("your_grid_region_static_id").widget().interactiveGrid("getSelectedRecords");

// If a row is selected
if (selectedRecords.length > 0) {
var record = selectedRecords[0];
var rowId = ig.getValue(record, "ROW_ID");  // Replace ROW_ID with the column name in your IG that holds the row id

    // Redirect to page 82 and pass the ROW_ID as a parameter (P82_ID)
    window.location.href = apex.util.makeApplicationUrl({pageId: 82}) + '&P82_ID=' + rowId;

} else {
alert("Please select a row.");
}

I am not able to open the page with above code.

I can open the page with this code

window.location.href = apex.util.makeApplicationUrl({pageId: 82}) +      '&P82_ID='

but unable to pass the row id.
Any help would be great full.

event.preventDefault() doesn’t work on form submission [closed]

This sounds like the stupidest problem I’ve ever encountered, but this simple thing doesn’t work. The page refreshes every time I press ‘Submit’ button. Any ideas why?

Here is my code:

const submitBtn = document.querySelector('.submit-btn');

const submitForm = function (event) {
  event.preventDefault();
  console.log('Hi');
};

submitBtn.addEventListener('submit', submitForm);
<form>
    <label>Input your facebook profile URL</label>
    <input type="text" />
    <button class="submit-btn">Submit</button>
</form>

JQuery javascript search filter not updating clearing value

I have the following javscript code which filters a table based on search criteria in the SearchInput field. I then added a clear button called clearSearch which is designed to empty the search field. It works to a certain extent until I clear what I type in the search which sets value of the search field as blank but at this point the search doesn’t update.

Any ideas how I can make the search reflect the clearing function?

Thanks

$(document).ready(function(){

  $("#SearchInput").on("keyup", function() {
    var value = $(this).val().toLowerCase();
    $("#Data tr").filter(function() {
      $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
    });
  });

  $("#clearSearch").click(function(){
  $("#SearchInput").val("");
  });

});

How to configure CORS correctly? [duplicate]

Currently, my CORS setup only allows access from specified domains depending on the environment. However, I can still perform operations from Postman, curl, etc. What’s going wrong?

const allowedOrigins = [
  'https://xxxx.app',
  'https://www.xxxx.app',
  'https://dev.xxxx.app',
  'https://www.dev.xxxx.app'
].map(origin => origin.replace(//$/, ''));

const corsOptions = {
  origin: function (origin, callback) {
    const normalizedOrigin = origin ? origin.replace(//$/, '') : null;

    if (!normalizedOrigin) {
      return callback(null, true);
    }

    if (allowedOrigins.includes(normalizedOrigin)) {
      return callback(null, true);
    } else {
      const msg = 'CORS origin not allowed: ' + normalizedOrigin;
      return callback(new Error(msg), false);
    }
  },
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], 
  allowedHeaders: ['Content-Type', 'Authorization'], 
  credentials: true,
};

app.options('*', cors()); 

if (process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'development') {
  app.use(cors(corsOptions));
} else {
  app.use(cors());
}

Multiplayer boardgame with timers

I am creating a multiplayer boardgame (similar to chess.com but for another game) where the users can create a game with a certain game time and then another player can join that game and play.

The flow right now is sort of like this:

  1. On load I fetch all game data including a move list which includes time left in milliseconds for player1 and player2 respectively. If no move was made I pick the game time since it is the start of the game.

  2. On client side I start a timer which ticks down time for the player who is starting the game.

  3. When the player makes a move I send this to the server which calculates the elapsed time for the move like this:

    let now = Date.now();
    let newRemainingTime = game.gameTime;
    if(game.moveList.length > 0){                
        const elapsedTime = now - game.lastMoveTimestamp;
        const playerRemainingTime = game.moveList.length > 0 ? game.moveList[game.moveList.length - 1].timeLeft[player] : game.gameTime;
        newRemainingTime = Math.max(0, playerRemainingTime - elapsedTime + game.timeIncrement);
    } 
    
  4. Then server (socketio) emits to both players that the game state is update and I update front end timers with the values I get from the new gamestate.

Under normal circumstances this works fine. The timers update in sync and server handles the time between moves. However I am experiences some issues with handling of connection issues, e.g.:

  • If a player reloads the page during his turn the front end timers will show he has time left as per the latest move (instead of latest move minus his thinking time minus the time he has been away from the page).

  • There might be cases where player1 leaves during opponents turn so the opponents time should tick down, then opponent makes a move during player1 abscence and then player1 time should tick down. When player1 returns the timings for both players are off.

Quesitons

  1. How should I handle timers for the users if something happens between moves without using too much performance on the server?

  2. Are there any other considerations that I need to account for with the timers?

JavaScript setInterval is not working. I am having issue displaying the contents of a specific part of my html code so that it fades in and out

I am trying to display some text on my web page so that it fades off and comes back after some time intervals. The code below is the complete code for the both the html part, css, and the JS part. I have done everything possible but all to no avail. I just want the callback function to be continuously called at certain time. I don’t know if I am doing it correctly. Please someone should help. If my explanation does not provide enough clarity I can still explain further. Thank you.

  var listCountries = ['South Africa', 'USA', 'Germany', 'France', 'Italy', 'South Africa', 'Australia', 'South Africa', 'Canada', 'Argentina', 'Saudi Arabia', 'Mexico', 'South Africa', 'South Africa', 'Venezuela', 'South Africa', 'Sweden', 'South Africa', 'South Africa', 'Italy', 'South Africa', 'United Kingdom', 'South Africa', 'Greece', 'Cuba', 'South Africa', 'Portugal', 'Austria', 'South Africa', 'Panama', 'South Africa', 'South Africa', 'Netherlands', 'Switzerland', 'Belgium', 'Israel', 'Cyprus'];
  var listPlans = ['$5000', '$15,500', '$18,000', '$19,000', '$28,000', '$37,000', '$41,000', '$6,900', '$7,500', '$42,500'];
  var transarray = ['just <b>invested</b>', 'has <b>withdrawn</b>', 'is <b>trading with</b>'];
  let interval = Math.floor(Math.random() * (40000 - 8000 + 1) + 8000);
  var run = setInterval(request, interval);

  function request() {
    clearInterval(run);
   let interval = Math.floor(Math.random() * (40000 - 8000 + 1) + 8000);
    var country = listCountries[Math.floor(Math.random() * listCountries.length)];
    var transtype = transarray[Math.floor(Math.random() * transarray.length)];
    var plan = listPlans[Math.floor(Math.random() * listPlans.length)];
    var msg = 'Someone from <b>' + country + '</b> ' + transtype + ' <a href="javascript:void(0);" onclick="javascript:void(0);">' + plan + '</a>';
    $(".mgm .txt").html(msg);
    $(".mgm").stop(true).fadeIn(300);
    window.setTimeout(function () {
      $(".mgm").stop(true).fadeOut(300);
    }, 10000);
    run = setInterval(request, interval);
  }
The html code
<div class="mgm" style="display: none;">
    <div class="txt" style="color:black;"></div>
</div>

The CSS code
<style>
    ::ms-value {
        color: black;
    }

    .mgm {
        bottom: 180px;
    }


    h4 {
        color: white;
    }
</style>

<style type="text/css">
        .mgm {
            border-radius: 7px;
            position: fixed;
            z-index: 90;
            bottom: 45%;
            right: 50px;
            background: #fff;
            padding: 10px 27px;
            box-shadow: 0px 5px 13px 0px rgba(0, 0, 0, .3);
        }

        .mgm a {
            font-weight: 700;
            display: block;
            color: #1c8e51;
        }

        .mgm a,
        .mgm a:active {
            transition: all .2s ease;
            color: #1c8e51;
        }
</style>

Why the newly added data is not reflecting in the table component of primevue?

I am trying to create a Expense Tracker where a super user could create user accounts and its data is stored inside a pinia store. The table component should detect the change in the user account array and reflect the newly added user in this table.

I’m new to vue3 and pinia.

File: store.js

import { defineStore } from 'pinia'
import { computed, ref, reactive } from 'vue'

export const Store = defineStore('finance', () => {
  const getDate = () => {
    const currentDate = new Date()
    return currentDate.toLocaleString('en-US', {
      month: 'short',
      day: 'numeric',
      year: 'numeric',
      hour: 'numeric',
      minute: 'numeric',
      second: 'numeric'
    })
  }

  const superUser = { email: '[email protected]', secret: 'Munich' }

  let userIdCount = 1
  const userAccounts = ref([
    {
      accountID: userIdCount++,
      accountName: 'Veer',
      balance: 250,
      created: getDate(),
      updated: '-'
    }
  ])

  const savingsHistory = ref([])
  const expenseHistory = ref([])
  // const stateAccount = reactive({
  //   userAccount: [
  //     {
  //       accountID: userIdCount++,
  //       accountName: 'Veer',
  //       balance: 250,
  //       created: getDate(),
  //       updated: '-'
  //     }
  //   ],
  //   savingsHistory: [],
  //   expenseHistory: []
  // })

  const addUser = (name, initialBalance) => {
    const userDetail = {
      accountID: userIdCount++,
      accountName: name,
      balance: initialBalance,
      created: getDate(),
      updated: '-'
    }
    console.log(userDetail)

    userAccounts.value.push(userDetail)
    console.log(`Array after: ${userAccounts.value}`)
  }

  const updateSaving = (id, saving) => {
    const account = userAccounts.value.find((acc) => acc.accountID === id)
    if (account) {
      account.updated = getDate()
      account.balance += saving
      console.log(`Savings Before Update: ${savingsHistory.value}`)

      savingsHistory.value.push({
        user: account.accountName,
        savings: saving,
        updated: account.updated
      })
      console.log(`Savings Updated: ${savingsHistory.value}`)
    }
  }

  const updateExpense = (id, expense) => {
    const account = userAccounts.value.find((acc) => acc.accountID === id)
    if (account && account.balance >= expense) {
      account.updated = getDate()
      account.balance -= expense
      expenseHistory.value.push({
        user: account.accountName,
        expense: expense,
        updated: account.updated
      })
      return true
    }
    return false
  }

  const state = reactive({
    showAccountFormStatus: false,
    showSavingsFormStatus: false,
    showExpenseFormStatus: false
  })

  const toggleAccountForm = () => (state.showAccountFormStatus = !state.showAccountFormStatus)
  const toggleSavingsForm = () => (state.showSavingsFormStatus = !state.showSavingsFormStatus)
  const toggleExpenseForm = () => (state.showExpenseFormStatus = !state.showExpenseFormStatus)

  const getFullName = computed(() => superUser.email.split('@')[0])
  const getUserAccounts = computed(() => [...userAccounts.value])

  return {
    superUser,
    getFullName,
    toggleAccountForm,
    toggleSavingsForm,
    toggleExpenseForm,
    addUser,
    state,
    userAccounts,
    savingsHistory,
    expenseHistory,
    updateSaving,
    updateExpense,
    getUserAccounts
  }
})

File: TableComponent.vue

<script setup>
import DataTable from 'primevue/datatable'
import Column from 'primevue/column'
import { Store } from '@/stores/store'

import { computed, nextTick } from 'vue'

// Initialize the store
const store = Store()

// // Access the user accounts directly from stateAccount

// console.log(userAccounts)

const userAccounts = computed(() => store.getUserAccounts)

console.log(userAccounts.value)

nextTick(() => {
  console.log('User Accounts:', userAccounts.value)
})

// console.log(userAccounts)
</script>

<template>
  <DataTable :value="userAccounts" showGridlines responsiveLayout="scroll">
    <Column field="accountID" header="Account-ID"></Column>
    <Column field="accountName" header="Account User"></Column>
    <Column field="balance" header="Balance"></Column>
    <Column field="created" header="Created-On"></Column>
    <Column field="updated" header="Updated-On"></Column>
  </DataTable>
</template>

Why it is not working as expected?

Need some help with clear explanation.

Create regex to find text between quotation marks, for this function

feedbackResultToast(false, result.error || "some text some text");

feedbackResultToast(false, "some text some text");

feedbackResultToast(false, result.error || "some text some text", true);

feedbackResultToast(false, result.error || `some text some text`);

i have this function(feedbackResultToast) inside my js file, i need to match them, and take only the text group between ” or ‘ or ` .
The regex should be written in c# .NET

i tried to do regex in c# .NET, but i can’t finish it
my regex:
feedbackResultToast,s*|s*[""'`]{1}([^""'`]*)[""'`]{1}(?:,s*[^)]*)?)

For example, my regex, matched also this piece of code, that is not right

if (data.action== "edit") {
or
textBtnModal: "Add",

#React why the page do not render?

if I use the following code, the page can work correct.

{videoRefs.current.map((videoRef, index) => ( (
          <div className='stream' key={videoRef.deviceId}>
            <video ref={videoRef.ref} autoPlay playsInline></video>
            <div className='overlay'><p>{devices[index]?.label || `鏡頭 ${index + 1}`}</p></div>
          </div>
        )))}

But when I add isVideoVisible[videoRef.deviceId], my video component will go wrong and just display the side bar

{videoRefs.current.map((videoRef, index) => ( isVideoVisible[videoRef.deviceId] && (
          <div className='stream' key={videoRef.deviceId}>
            <video ref={videoRef.ref} autoPlay playsInline></video>
            <div className='overlay'><p>{devices[index]?.label || `鏡頭 ${index + 1}`}</p></div>
          </div>
        )))}
import React, { useEffect, useRef, useState } from 'react';
import './App.css';
import Switch from '@mui/material/Switch';

function App() {
  const videoRefs = useRef([]); // 使用空數組來儲存 video 元素的引用
  const label = { inputProps: { 'aria-label': 'Switch demo' } };
  const [devices, setDevices] = useState([]); // 用於存儲設備列表
  const [streams, setStreams] = useState({}); // 存儲每個設備的流
  const [isVideoVisible, setIsVideoVisible] = useState({});


  // TODO: 處理開關變更事件,開啟一個鏡頭時,只能出現在一個視窗中,其他 conponent 需要關閉
  const handleSwitchChange = (deviceId, checked) => {
    if (checked) {

      navigator.mediaDevices.getUserMedia({video: { deviceId: deviceId }})
      .then(stream => {
        const videoRef = videoRefs.current.find(ref => ref.deviceId === deviceId);
        if (videoRef && videoRef.ref.current) {
          videoRef.ref.current.srcObject = stream; // 設置視頻流
          setStreams(prevStreams => ({
            ...prevStreams,
            [deviceId]: stream,
          }));
          setIsVideoVisible(prev => ({ ...prev, [deviceId]: true })); // 顯示視頻
        }
      }).catch(err => {
        console.error('無法存取攝像頭:', err);
      });

    } else {
      if (streams[deviceId]) {
        console.log('關閉前的 stream:', streams);
        streams[deviceId].getTracks().forEach(track => track.stop()); // 停止流
        setStreams(prevStreams => {
          const newStreams = { ...prevStreams };
          delete newStreams[deviceId]; // 移除流
          return newStreams;
        });
        setIsVideoVisible(prev => ({ ...prev, [deviceId]: false })); // 隱藏視頻
        // 清除視頻元素的 srcObject
        const videoRef = videoRefs.current.find(ref => ref.deviceId === deviceId);
        if (videoRef && videoRef.ref.current) {
          videoRef.ref.current.srcObject = null; // 清除視頻元素的 srcObject
        }
      }
      console.log('關閉後剩餘的流:', streams);
    }
  };

  useEffect(() => {
    navigator.mediaDevices.enumerateDevices()
      .then(devices => {
        const videoDevices = devices.filter(device => device.kind === 'videoinput');
        setDevices(videoDevices); 
        console.log('找到的攝像頭:', videoDevices);

        // 初始化 videoRefs
        videoRefs.current = videoDevices.map(device => ({ deviceId: device.deviceId, ref: React.createRef() }));

        videoDevices.forEach(device => {
          navigator.mediaDevices.getUserMedia({
            video: { deviceId: device.deviceId }
          }).then(stream => {
            const videoRef = videoRefs.current.find(ref => ref.deviceId === device.deviceId);
            console.log('videoRef',videoRef);

            handleSwitchChange(device.deviceId, true);
            
            if (videoRef && videoRef.ref.current) {
              videoRef.ref.current.srcObject = stream;
              setStreams(prevStreams => ({
                ...prevStreams,
                [device.deviceId]: stream,
              }));
          
            }
          }).catch(err => {
            console.error('無法存取攝像頭:', err);
          });
        });
        
      })
      .catch(err => {
        console.error('無法取得媒體設備:', err);
        setLoading(false); // 如果出現錯誤,則停止加載
      });
  }, []); 


  return (
    <>
      <div className='sidebar'>
        <h2>LUXGroup</h2>
        {devices.map((device, index) => (
          <div key={device.deviceId}>
            {device.label || `鏡頭 ${index + 1}`} 
            <Switch
              {...label}
              defaultChecked
              onChange={(e) => handleSwitchChange(device.deviceId, e.target.checked)}
            />
          </div>
        ))}
      </div>
      <div className='stream-container'>
        {console.log('hihi')}
        {videoRefs.current.map((videoRef, index) => ( (
          <div className='stream' key={videoRef.deviceId}>
            <video ref={videoRef.ref} autoPlay playsInline></video>
            <div className='overlay'><p>{devices[index]?.label || `鏡頭 ${index + 1}`}</p></div>
          </div>
        )))}
          {/* isVideoVisible[videoRef.deviceId] */}
      </div>
    </>
  );
}

export default App;

I expected that when I use isVideoVisible[videoRef.deviceId] ,I can handle the page component by the switch

Search Box in GridView ASP.NET

I’m working on an ASP.NET WebForms application where I want to add a search box on top of each column header in a grid. The search box is supposed to filter the grid data based on user input.

Here’s what I’ve implemented so far:

  • I have placed TextBox controls inside the grid’s header template for each column.

  • I am handling the search operation using the OnTextChanged event in the ASPX.CS file and also tried with JavaScript in the ASPX file.

Problem:

The search boxes are displayed on the grid, but I am unable to type into them. They appear to be uneditable, and I’m not sure why the input fields are not working as expected.

$(document).ready(function () {
    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);

    function EndRequestHandler(sender, args) {
        var rows1 = $('table#<%= Table1.ClientID %> tr:last').index() + 1;

        if (rows1 > 1) {
            // Initialize DataTable with column-based search functionality
            var table = $("#<%=Table1.ClientID%>").DataTable({
                stateSave: true,
                pagingType: "full_numbers",
                lengthMenu: [[10, 25, 50, -1], [10, 25, 50, "All"]],
                dom: '<"top"Bfl>rt<"bottom"ip><"clear">',
                buttons: [
                    { extend: 'copy', className: 'btn-sm btn-default' },
                    { extend: 'excel', className: 'btn-sm btn-success', filename: function () { return getExportFileName(); } },
                    { extend: 'print', className: 'btn-sm btn-danger' }
                ],
                responsive: false,
                retrieve: false,
                ordering: false,
            });

            // Apply search on each column
            $("#<%=Table1.ClientID%> thead input.search-column").on('keyup change', function () {
                var colIndex = $(this).closest('th').index();  // Get the index of the column
                table.column(colIndex).search(this.value).draw();  // Perform search
            });
        }
    }

    Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(function (evt, args) {
        var rows1 = $('table#<%= Table1.ClientID %> tr:last').index() + 1;

        if (rows1 > 1) {
            var table = $("#<%=Table1.ClientID%>").DataTable({
                stateSave: true,
                pagingType: "full_numbers",
                lengthMenu: [[10, 25, 50, -1], [10, 25, 50, "All"]],
                dom: '<"top"Bfl>rt<"bottom"ip><"clear">',
                buttons: [
                    { extend: 'copy', className: 'btn-sm btn-default' },
                    { extend: 'excel', className: 'btn-sm btn-success', filename: function () { return getExportFileName(); } },
                    { extend: 'print', className: 'btn-sm btn-danger' }
                ],
                responsive: false,
                retrieve: false,
                ordering: false,
            });

            // Apply search on each column on initial load
            $("#<%=Table1.ClientID%> thead input.search-column").on('keyup change', function () {
                var colIndex = $(this).closest('th').index();
                table.column(colIndex).search(this.value).draw();
            });
        }
    });
});

Path Alias Not Working in Bun Project Despite Correct Configuration

I config path alias following this guide: https://bun.sh/guides/runtime/tsconfig-paths. But it’s not work

I create a Bun project (I’m planning to migrate a Node app to Bun) by these steps:

  1. mkdir bun-test && cd bun-test && bun init

  2. After init project, I add to tsconfig.ts

{
  "compilerOptions": {
    ...
    "baseUrl": "./src",
    "paths": {
      "config": ["./config/appConfig.ts"]
    }
  }
}
  1. Create src/config/appConfig.ts
export default {
  message: "My first bun application",
};
  1. Modify src/index.ts.
import appConfig from "config";

console.log(appConfig.message);
  1. VSCode intellisense resolve the path well, but when run app bun run ./src it throw error
error: Cannot find package "config" from "/bun-test/src/index.ts"

Bun v1.1.29 (Linux x64)

What problem here? Am i missing some step?

unable to see uploaded image preview in Editor.js on Vue Js 3

working with Laravel 10 and Vue Js 3 with Editor.js in my blog app. I have following createBlog.vue file with embedded Editor.js

<template>
  <!-- Input field for title -->
          <div class="_input_field">
            <Input v-model="title" type="text" placeholder="Enter title" />
          </div>

          <div class="_overflow _table_div blog_editor">
            <!-- Editor.js container -->
            <div ref="editorContainer" class="editor-container"></div>
          </div>

          <!-- Save button to save the content -->
          <div class="_input_field">
            <Button @click="save">Save</Button>
          </div>
</template>

<script>
import EditorJS from '@editorjs/editorjs';
import Header from '@editorjs/header';
import List from '@editorjs/list';
import Image from '@editorjs/image';

export default {
  data() {
    return {
      editor: null,  // The EditorJS instance
      title: '',     // Data for the title input
    };
  },
  mounted() {
    
    const csrfToken = document.head.querySelector('meta[name="csrf-token"]').getAttribute('content');

    // Initialize the Editor.js instance
    this.editor = new EditorJS({
      holder: this.$refs.editorContainer, // Reference to the div for Editor.js
      tools: {
        header: Header,  // Adding the Header block tool
        list: List,      // Adding the List block tool
        image: {
          class: Image,
          config: {
            endpoints: {
              byFile: 'http://localhost:8000/createBlog', // URL to upload image by file
             byUrl: null, // Not using by URL for now
           },
            field: 'image',  // The field name for file upload
           types: 'image/png, image/jpg, image/jpeg', // Allow image file types
            additionalRequestHeaders: {
              'X-CSRF-TOKEN': document.head.querySelector('meta[name="csrf-token"]').content
             }, // Ensure CSRF token is added if necessary
            captionPlaceholder: 'Enter image caption',
            buttonContent: 'Select Image',
            onUploadError: (error) => {
      console.error('Image upload failed:', error);
     },
          }
        },
      },
      autofocus: true, // Automatically focus the editor
      onReady: () => {
        console.log('Editor.js is ready to work!');
      },
    });
  },
  methods: {
    save() {
      // Save the content from Editor.js
      this.editor.save().then((outputData) => {
        console.log('Content saved:', outputData);

        // Combine the title and editor content
        const postData = {
          title: this.title, // The title entered by the user
          content: outputData // The content from the editor
        };

        // Now you can send `postData` to your server
        console.log('Post Data:', postData);
      }).catch((error) => {
        console.error('Saving failed:', error);
      });
    }
  },
  beforeUnmount() {
    // Clean up the editor instance
    if (this.editor) {
      this.editor.destroy();
      this.editor = null;
    }
  }
};

</script>

and controller for createBlog is

//upload Editor Image function
    public function uploadEditorImage(Request $request) {
        $this->validate($request, [
            'image' => 'required|mimes:jpeg,jpg,png',
        ]);
        $picName = time().'.'.$request->image->extension();
        $request->image->move(public_path('uploads'), $picName);
        return response()->json([
            'success' => 1,
            'file' => [
                'url' => "http://localhost:8000/uploads/$picName"
            ]
        ])->header('Content-Type', 'application/json');
       // return $picName;
    }

web.php is

Route::post('createBlog',[AdminController::class,'uploadEditorImage']);

now I need when I uploaded an image via editor preview of the image on the editor. but currently editor uploaded image to public/uploads folder successfully but not preview image on the editor then how could I fix this problem here?

Electron Win+D minimization issue on Windows

I want to make a software similar to a desktop sticky note and develop it using Electron. Currently, on the Windows side, I have encountered some problems:
1.Can Electron prevent minimization when Win+D is pressed?
2.If the problem of not being able to prevent minimization with Win+D cannot be solved, then after minimization, I created a background through the Tray that comes with Electron and set up an event.
tray.on('click', () => mainWindow.show())

The above code can run normally, but when I click on other areas of the desktop, my application is zoomed out again.
Or when I click on a third-party application in the taskbar, my application is also displayed normally.
I have seen some other solutions. For example:

mainWindow.on('minimize', (e) => {
    e.preventDefault()
    setTimeout(() => mainWindow.restore(), 200)
})

However, the listening of the above code is ineffective.

BTW: I set minimizable to false and alwaysOnTop is effective, but the user experience is not good.

Electron Version: 29.1.0

BrowserWindow

win = new BrowserWindow({
    type: "toolbar",
    frame: false,
    skipTaskbar: true,
    transparent: true,
    minimizable: false,
    ...
  });