Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The copy button is invalid. #250

Closed
rankaiyx opened this issue Dec 16, 2024 · 18 comments · Fixed by #251
Closed

The copy button is invalid. #250

rankaiyx opened this issue Dec 16, 2024 · 18 comments · Fixed by #251
Labels

Comments

@rankaiyx
Copy link

rankaiyx commented Dec 16, 2024

version:
ghcr.io/fmaclen/hollama:latest (0.23.2)

Tested browser:
chrome
edge
firefox

@fmaclen
Copy link
Owner

fmaclen commented Dec 16, 2024

What do you mean by "is invalid"?
Are all Copy buttons not working or one in particular?

@rankaiyx
Copy link
Author

All Copy buttons not working

@fmaclen
Copy link
Owner

fmaclen commented Dec 16, 2024

Is it possible you are accessing that Docker container on an external connection over HTTP and not HTTPS?

Assuming you are on the latest version of Chrome, do you see any errors/warnings in Inspector when you click on the button?

@rankaiyx
Copy link
Author

Can't you reproduce it over there?
HTTP
no errors/warnings

@rankaiyx
Copy link
Author

I'm using "OpenAI: Compatible servers (i.e. llama.cpp)"

@fmaclen
Copy link
Owner

fmaclen commented Dec 16, 2024

HTTP

That is likely the problem, browsers don't allow copy/paste functionality over HTTP (unless you are hosting the server on localhost). If you are hosting Hollama in an external server you must use HTTPS.

@fmaclen fmaclen closed this as completed Dec 16, 2024
@fmaclen
Copy link
Owner

fmaclen commented Dec 16, 2024

You can try creating a tunnel using HTTPS for free with Cloudflare or Ngrok.

@rankaiyx
Copy link
Author

Okay, I'll test it.
But it seems that HTTP just disallows reading the clipboard, not writing the clipboard.

@rankaiyx
Copy link
Author

This is indeed the reason. After I forward the port to the local area, it will be fine.
However, it should be possible to write to the clipboard under http.

At least the following projects can implement this feature.
https://github.com/open-webui/open-webui

Maybe we can do some research about it.

@fmaclen
Copy link
Owner

fmaclen commented Dec 16, 2024

Glad it worked!

Maybe we can do some research about it.

Interesting, I just took a quick look at the way open-webui handles the clipboard and at a glance it looks like they are using pretty much the same logic Hollama does. Will have to take a closer look.

@rankaiyx
Copy link
Author

The Clipboard API requires HTTPS,
The following methods should be HTTP compatible.

function copyToClipboard(text) {
// Try to use modern Clipboard API
if (navigator.clipboard && window.isSecureContext) {
return navigator.clipboard.writeText(text);
}

// Fallback to older method for compatibility
const textArea = document.createElement('textarea');
textArea.value = text;
textArea.style.position = 'fixed';
textArea.style.left = '-999999px';
textArea.style.top = '-999999px';
document.body.appendChild(textArea);
textArea.focus();
textArea.select();

try {
const successful = document.execCommand('copy');
document.body.removeChild(textArea);
return successful;
} catch (err) {
document.body.removeChild(textArea);
console.error('Unable to copy', err);
return false;
}
}

@rankaiyx
Copy link
Author

I'll try it, if it can be solved, maybe I can send a PR.

@rankaiyx
Copy link
Author

Well, I don't know which files should be modified.
I tried to modify /app/src/lib/components/ButtonCopy.svelte directly in the docker container, but it didn't seem to work.

@fmaclen
Copy link
Owner

fmaclen commented Dec 16, 2024

Appreciate the effort but the solution mentioned above looks a bit like a hack. The copy functionality has been implemented for several months and this issue has never come up so I'd rather not add a workaround for what it seems to be an anti-pattern.

What I'd be down to implement is to check window.isSecureContext and if not then render a flash alert with a message that explains why the feature isn't working.

@rankaiyx
Copy link
Author

rankaiyx commented Dec 19, 2024

I noticed that open-webui considered HTTP compatibility.
Lines 225 to 265 in this file:
https://github.com/open-webui/open-webui/blob/main/src/lib/utils/index.ts

The method used by open-webui is:

export const copyToClipboard = async (text) => {
	let result = false;
	if (!navigator.clipboard) {
		const textArea = document.createElement('textarea');
		textArea.value = text;

		// Avoid scrolling to bottom
		textArea.style.top = '0';
		textArea.style.left = '0';
		textArea.style.position = 'fixed';

		document.body.appendChild(textArea);
		textArea.focus();
		textArea.select();

		try {
			const successful = document.execCommand('copy');
			const msg = successful ? 'successful' : 'unsuccessful';
			console.log('Fallback: Copying text command was ' + msg);
			result = true;
		} catch (err) {
			console.error('Fallback: Oops, unable to copy', err);
		}

		document.body.removeChild(textArea);
		return result;
	}

	result = await navigator.clipboard
		.writeText(text)
		.then(() => {
			console.log('Async: Copying to clipboard was successful!');
			return true;
		})
		.catch((error) => {
			console.error('Async: Could not copy text: ', error);
			return false;
		});

	return result;
};

@rankaiyx
Copy link
Author

The home local area network is a common use case. In this scenario, HTTP is the easiest to deploy and sufficient.

@fmaclen
Copy link
Owner

fmaclen commented Dec 19, 2024

The home local area network is a common use case. In this scenario, HTTP is the easiest to deploy and sufficient.

I hear ya. We recently had another issue where we were using cryptoUUID() to generate id's but that library is also not available over HTTP.

That one wasn't too bad because we weren't using it for privacy reasons, but in this case it might become a vulnerability, in addition to doument.executeCommand() being flagged as deprecated which means this hack will eventually not be possible.

I'd be down to implementing the workaround as long as we alert the user that they are using the feature on an insecure context, for example:

	function copyContent() {
		if (navigator.clipboard && window.isSecureContext) {
			navigator.clipboard.writeText(content);
		} else {
			const textArea = document.createElement('textarea');
			textArea.value = content;
			document.body.appendChild(textArea);
			textArea.select();
			try {
				document.execCommand('copy');
				toast.warning('Content copied, but your connection is not private');
			} catch (e) {
				console.error(e);
				toast.error("Couldn't copy content. Connection is not private");
			}
			document.body.removeChild(textArea);
		}
	}

@fmaclen
Copy link
Owner

fmaclen commented Dec 19, 2024

🎉 This issue has been resolved in version 0.24.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants