lencx / ChatGPT

🔮 ChatGPT Desktop Application (Mac, Windows and Linux)
https://nofwl.com
51.74k stars 5.81k forks source link

[Feature] Export to image icons that were in the bottom right corner to be brought back… #1156

Open kpapiez opened 7 months ago

kpapiez commented 7 months ago

Feature description

These options were located in the bottom left corner. Right now I can only share with the link (top right).

Motivation

To have the functionality that previously existed.

Alternatives

Sharing to access the chat from a link and later trying to save it as PDF but it doesn't save the whole chat, just on the screen so less than one page.

Alternatively there could be an Export option in the menu up top.

Additional context

No response

lduperval commented 7 months ago

I concur. For some reason, the export buttons have disappeared. I use them quite often (especially the export to Markdown button) and they disappeared recently, although I have not updated the export.js file. I suspect it may be a conflict with the new Custom GPT additions to the ChatGPT UI, but I'm not sure.

At any rate, if someone knows how to fix the export.js file to bring back the icons or — even better—how to add it to the top menu and use a keyboard shortcut to do the export, that would be great!

jdrx99 commented 7 months ago

!!This should be labelled as a bug rather than feature as it already exists!!

Facing the same issue all the export buttons are missing on my install of windows 11 (via winget) latest 1.1.0 version. These options were the primary reason to even install the app. It is of utmost importance and must be corrected at the earliest otherwise this app is pretty much not needed. export to markdown, pdf, image all were very important aspects which are needed.

Screenshot 2023-12-09 123318

Using on windows 11 (installed with winget)

lduperval commented 7 months ago

After doing a bit of debugging with ChatGPT, I think I found the problem. In export.js, it's looking for a specific element on the webpage and that element seems to no longer be there. I suspect it was changed in the GPT release after Nov 6. If someone know enough about CSS and Javascript, this seems to be the problematic code in the btnInit() function:

const navActionArea = document.querySelector('nav .border-t > div');

This element doesn't seem to exist anymore in the interface so nothing happens. If someone know which element replaced it, it should be possible to change the query and the buttons will be able to be added just abov the profile menu button.

lduperval commented 7 months ago

So if you change the line above to:

  const navActionArea = document.querySelector('nav .flex.flex-col.pt-2');

The buttons reappear. However, they are stacked vertically. If someone can explain how to make them align horizontally, that would take care of the problem... for now!

Of courset, the ideal wuould be to add the export veature as a menu option with a keyboard shortcut but I don't know whow to do that.

lduperval commented 7 months ago

I found it, with the help of chatGPT. So if you modify the beginning of the btnInit() funtion to look like this, the code should work (lines 209-225):

function btnInit() {
    const intervalId = setInterval(function () {
//      const navActionArea = document.querySelector('nav .border-t > div');
      const navActionArea = document.querySelector('nav .flex.flex-col.pt-2');
      const addArea = document.querySelector('#chatgpt-nav-action-area');
      if (!navActionArea || addArea) return;
      const cloneNode = document.createElement('div');
      cloneNode.id = 'chatgpt-nav-action-area';
      cloneNode.classList = `${navActionArea.className} border-b border-white/20 mb-2 pb-2`;
      cloneNode.style.flexDirection = 'row'; // Override flex-direction
      cloneNode.appendChild(addBtn('png'));
      cloneNode.appendChild(addBtn('pdf'));
      cloneNode.appendChild(addBtn('md'));
      cloneNode.appendChild(addBtn('refresh'));
      navActionArea.parentNode.insertBefore(cloneNode, navActionArea);
      clearInterval(intervalId);
jdrx99 commented 7 months ago

I found it, with the help of chatGPT. So if you modify the beginning of the btnInit() funtion to look like this, the code should work (lines 209-225):

function btnInit() {
    const intervalId = setInterval(function () {
//      const navActionArea = document.querySelector('nav .border-t > div');
    const navActionArea = document.querySelector('nav .flex.flex-col.pt-2');
      const addArea = document.querySelector('#chatgpt-nav-action-area');
      if (!navActionArea || addArea) return;
      const cloneNode = document.createElement('div');
      cloneNode.id = 'chatgpt-nav-action-area';
      cloneNode.classList = `${navActionArea.className} border-b border-white/20 mb-2 pb-2`;
    cloneNode.style.flexDirection = 'row'; // Override flex-direction
      cloneNode.appendChild(addBtn('png'));
      cloneNode.appendChild(addBtn('pdf'));
      cloneNode.appendChild(addBtn('md'));
      cloneNode.appendChild(addBtn('refresh'));
      navActionArea.parentNode.insertBefore(cloneNode, navActionArea);
      clearInterval(intervalId);

this works! you should put in a pull request to update the main fork!

lduperval commented 7 months ago

Hmm, I've nver done that. I'll take a look and see

CMakey commented 5 months ago

I found it, with the help of chatGPT. So if you modify the beginning of the btnInit() funtion to look like this, the code should work (lines 209-225):

function btnInit() {
    const intervalId = setInterval(function () {
//      const navActionArea = document.querySelector('nav .border-t > div');
    const navActionArea = document.querySelector('nav .flex.flex-col.pt-2');
      const addArea = document.querySelector('#chatgpt-nav-action-area');
      if (!navActionArea || addArea) return;
      const cloneNode = document.createElement('div');
      cloneNode.id = 'chatgpt-nav-action-area';
      cloneNode.classList = `${navActionArea.className} border-b border-white/20 mb-2 pb-2`;
    cloneNode.style.flexDirection = 'row'; // Override flex-direction
      cloneNode.appendChild(addBtn('png'));
      cloneNode.appendChild(addBtn('pdf'));
      cloneNode.appendChild(addBtn('md'));
      cloneNode.appendChild(addBtn('refresh'));
      navActionArea.parentNode.insertBefore(cloneNode, navActionArea);
      clearInterval(intervalId);

hello , I had changed the code in export.js from 209-225 just like this , after restarting GPT client , there is nothing changed . I'm a little confused how u work with the tab of full btnInit function . can u show it ?

I think the error was caused by the wrong tab after I changed code. It looks like this:

    function btnInit() {
        const intervalId = setInterval(function () {
    //      const navActionArea = document.querySelector('nav .border-t > div');
          const navActionArea = document.querySelector('nav .flex.flex-col.pt-2');
          const addArea = document.querySelector('#chatgpt-nav-action-area');
          if (!navActionArea || addArea) return;
          const cloneNode = document.createElement('div');
          cloneNode.id = 'chatgpt-nav-action-area';
          cloneNode.classList = `${navActionArea.className} border-b border-white/20 mb-2 pb-2`;
          cloneNode.style.flexDirection = 'row'; // Override flex-direction
          cloneNode.appendChild(addBtn('png'));
          cloneNode.appendChild(addBtn('pdf'));
          cloneNode.appendChild(addBtn('md'));
          cloneNode.appendChild(addBtn('refresh'));
          navActionArea.parentNode.insertBefore(cloneNode, navActionArea);
          clearInterval(intervalId);
        return function () {
          const context = this;
          const args = arguments;
          clearTimeout(timeout);
          timeout = setTimeout(() => {
            func.apply(context, args);
          }, wait);
        };
      }
      const target = document.querySelector('nav');
      const debouncedFunction = debounce(function () {
        btnInit();
      }, 300);
      const observer = new MutationObserver(debouncedFunction);
      const config = { attributes: true, childList: true, characterData: true, subtree: true };
      observer.observe(target, config);
    }, 1000);
  }
cemerson commented 5 months ago

I had trouble deciphering a fix above but here's what worked for me (for anyone needing a bandaid/fix until this is fixed in the main app): 1) Go to control center / go to "Scripts" / edit "export.js" 2) Go to around like 211 and replace the corresponding const navActionArea declaration with this:

      // const navActionArea = document.querySelector('nav .border-t > div');
      const navActionArea = document.querySelector('main form'); 

3) Save and Relaunch / Buttons should show up in left nav pane bottom ... usually (?)

NOTE: PDF seems a bit wonky (idk if that's my chatgpt log or the pdf functions are broken) but Markdown at least works.

CMakey commented 5 months ago

I had trouble deciphering a fix above but here's what worked for me (for anyone needing a bandaid/fix until this is fixed in the main app):

  1. Go to control center / go to "Scripts" / edit "export.js"
  2. Go to around like 211 and replace the corresponding const navActionArea declaration with this:
      // const navActionArea = document.querySelector('nav .border-t > div');
      const navActionArea = document.querySelector('main form'); 
  1. Save and Relaunch / Buttons should show up in left nav pane bottom ... usually (?)

NOTE: PDF seems a bit wonky (idk if that's my chatgpt log or the pdf functions are broken) but Markdown at least works.

this seems doesn't work for me... so sad

lduperval commented 5 months ago

@CMakey You're right, the tabs were not aligned properly in my original post. All of the tabs should be converted to two spaces.

Here is the correct fix, I hope:

  function btnInit() {
    const intervalId = setInterval(function () {
      // const navActionArea = document.querySelector('nav .border-t > div');
      const navActionArea = document.querySelector('nav .flex.flex-col.pt-2');

      const addArea = document.querySelector('#chatgpt-nav-action-area');
      if (!navActionArea || addArea) return;
      const cloneNode = document.createElement('div');
      cloneNode.id = 'chatgpt-nav-action-area';
      cloneNode.classList = `${navActionArea.className} border-b border-white/20 mb-2 pb-2`;
      cloneNode.style.flexDirection = 'row'; // Override flex-direction
      cloneNode.appendChild(addBtn('png'));
      cloneNode.appendChild(addBtn('pdf'));
      cloneNode.appendChild(addBtn('md'));
      cloneNode.appendChild(addBtn('refresh'));
      navActionArea.parentNode.insertBefore(cloneNode, navActionArea);
      clearInterval(intervalId);

      function debounce(func, wait) {
        let timeout;
        return function () {
          const context = this;
          const args = arguments;
          clearTimeout(timeout);
          timeout = setTimeout(() => {
            func.apply(context, args);
          }, wait);
        } ;
      }
      const target = document.querySelector('nav');
      const debouncedFunction = debounce(function () {
        btnInit();
      }, 300);
      const observer = new MutationObserver(debouncedFunction);
      const config = { attributes: true, childList: true, characterData: true, subtree: true };
      observer.observe(target, config);
    }, 1000);
  }

@cemerson I tried your code but the icons disappeared in my version of the app. Not sure why.

Tritaya commented 1 month ago

No @cemerson neither @lduperval solution works for me. Both solutions provide the buttons on top but they trigger an error message in console log (I used markdown export button):

Uncaught (in promise) Scope not defined for URL `https://chatgpt.com/`. See https://tauri.app/v1/api/config/#securityconfig.dangerousremotedomainipcaccess and https://docs.rs/tauri/1/tauri/scope/struct.IpcScope.html#method.configure_remote_access
exportMarkdown  @   VM17:57
await in exportMarkdown (async)     
btn.onclick @   VM17:270
lduperval commented 1 month ago

@Tritaya the new versions of ChatGPT broke the code