Last active
February 29, 2024 05:12
-
-
Save bravekingzhang/aa47fa43d1022bbcd1547979d3931e3a to your computer and use it in GitHub Desktop.
让notion支持插入图片
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Image search for editor with giphy | |
// @namespace http://tampermonkey.net/ | |
// @version 2024-02-28 | |
// @description Search and insert images into Notion | |
// @author brzhang | |
// @match https://*/* | |
// @grant GM_setClipboard | |
// @grant GM_setValue | |
// @grant GM_getValue | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
function showSearchLoading() { | |
document.getElementById('imageSearchButton').innerHTML = 'Searching...'; | |
document.getElementById('imageSearchButton').disabled = true; | |
// create a loading html element ,and put it in the search results | |
const loadingHtml = `<div id="imageSearchLoading" style="margin-top:10px;">Loading...</div>`; | |
document | |
.getElementById('imageSearchResults') | |
.insertAdjacentHTML('beforeend', loadingHtml); | |
} | |
// Function to create the search panel,center the panel on the screen ,close it when user clicks outside | |
function createSearchPanel() { | |
const panelHTML = ` | |
<div | |
id="imageSearchPanel" | |
style=" | |
display: flex; | |
flex-direction: column; | |
overflow: auto; | |
width: 500px; | |
position: fixed; | |
top: 50%; | |
left: 50%; | |
transform: translate(-50%, -50%); | |
z-index: 9999; | |
background: #ffffff; | |
padding: 20px; | |
border-radius: 8px; | |
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); | |
" | |
> | |
<div | |
style=" | |
display: flex; | |
justify-content: space-between; | |
align-items: center; | |
margin-top: 10px; | |
" | |
> | |
<input | |
type="text" | |
id="imageSearchQuery" | |
placeholder="Search for images" | |
style=" | |
width: calc(100% - 80px); | |
padding: 10px; | |
border-radius: 5px; | |
border: 1px solid #ccc; | |
box-sizing: border-box; | |
" | |
/> | |
<button | |
id="imageSearchButton" | |
style=" | |
padding: 10px; | |
border: none; | |
background-color: #4caf50; | |
color: white; | |
border-radius: 5px; | |
cursor: pointer; | |
transition: background-color 0.3s ease; | |
" | |
> | |
Search | |
</button> | |
</div> | |
<button | |
id="settingsButton" | |
style=" | |
position: absolute; | |
top: 0; | |
left: 0; | |
margin-bottom: 10px; | |
border: none; | |
background-color: #007bff; | |
color: white; | |
border-radius: 5px; | |
cursor: pointer; | |
transition: background-color 0.3s ease; | |
" | |
> | |
Settings | |
</button> | |
<button | |
id="closeButton" | |
style=" | |
position: absolute; | |
top: 0; | |
right: 0; | |
margin-bottom: 10px; | |
border: none; | |
background-color: #dc3545; | |
color: white; | |
border-radius: 5px; | |
cursor: pointer; | |
transition: background-color 0.3s ease; | |
" | |
> | |
X | |
</button> | |
<div | |
id="imageSearchResults" | |
style=" | |
display: flex; | |
flex-wrap: wrap; | |
max-height: 500px; | |
overflow-y: auto; | |
" | |
></div> | |
</div> | |
`; | |
document.body.insertAdjacentHTML('beforeend', panelHTML); | |
document | |
.getElementById('imageSearchButton') | |
.addEventListener('click', function() { | |
const query = document.getElementById('imageSearchQuery').value; | |
searchImages(query); | |
}); | |
document.getElementById('imageSearchQuery').focus(); | |
document | |
.getElementById('imageSearchQuery') | |
.addEventListener('keydown', function(event) { | |
// 检查是否是回退键被按下 | |
if (event.key === 'Backspace') { | |
// 阻止事件的默认行为(在这里是删除前一个字符) | |
event.preventDefault(); | |
// 停止事件继续传播 | |
event.stopPropagation(); | |
// 你可以在这里添加代码来手动处理输入框的文本删除逻辑 | |
// 比如手动删除输入框中的最后一个字符 | |
let currentValue = this.value; | |
this.value = currentValue.substring(0, currentValue.length - 1); | |
} | |
}); | |
//copy parse for imageSearchQuery | |
document | |
.getElementById('imageSearchQuery') | |
.addEventListener('paste', function(event) { | |
event.preventDefault(); | |
event.stopPropagation(); | |
const text = event.clipboardData.getData('text/plain'); | |
document.getElementById('imageSearchQuery').value = text; | |
}); | |
document | |
.getElementById('closeButton') | |
.addEventListener('click', function() { | |
document.getElementById('imageSearchPanel').remove(); | |
}); | |
document | |
.getElementById('settingsButton') | |
.addEventListener('click', function() { | |
createSettingsPanel(); | |
}); | |
} | |
// Function to create the settings panel | |
function createSettingsPanel() { | |
// Check if the settings panel already exists | |
if (document.getElementById('settingsPanel')) { | |
return; | |
} | |
const settingsHTML = ` | |
<div | |
id="settingsPanel" | |
style=" | |
position: absolute; | |
top: 50%; | |
left: 50%; | |
width: max-content; | |
transform: translate(-50%, -50%); | |
z-index: 10000; | |
background: #fff; | |
padding: 10px; | |
border-radius: 8px; | |
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); | |
" | |
> | |
<label for="api-key-input">Giphy API Key:<a href="https://developers.giphy.com">?</a></label> | |
<input | |
type="text" | |
id="api-key-input" | |
placeholder="Enter your API key" | |
style=" | |
padding: 10px; | |
border-radius: 5px; | |
border: 1px solid #ccc; | |
box-sizing: border-box; | |
" | |
/> | |
<button | |
id="save-api-key" | |
style=" | |
padding: 10px; | |
border: none; | |
background-color: #4caf50; | |
color: white; | |
border-radius: 5px; | |
cursor: pointer; | |
transition: background-color 0.3s ease; | |
" | |
> | |
Save | |
</button> | |
<button | |
id="close-settings" | |
style=" | |
padding: 10px; | |
border: none; | |
background-color: #dc3545; | |
color: white; | |
border-radius: 5px; | |
cursor: pointer; | |
transition: background-color 0.3s ease; | |
" | |
> | |
Close | |
</button> | |
</div> | |
`; | |
document.body.insertAdjacentHTML('beforeend', settingsHTML); | |
const apiKey = GM_getValue('apiKey', ''); | |
if (apiKey) { | |
document.getElementById('api-key-input').value = apiKey; | |
} | |
document | |
.getElementById('save-api-key') | |
.addEventListener('click', saveApiKey); | |
document | |
.getElementById('close-settings') | |
.addEventListener('click', function() { | |
document.getElementById('settingsPanel').remove(); | |
}); | |
document.getElementById('api-key-input').focus(); | |
document | |
.getElementById('api-key-input') | |
.addEventListener('keydown', function(event) { | |
if (event.key === 'Enter') { | |
saveApiKey(); | |
} | |
if (event.key === 'Backspace') { | |
// 阻止事件的默认行为(在这里是删除前一个字符) | |
event.preventDefault(); | |
// 停止事件继续传播 | |
event.stopPropagation(); | |
// 你可以在这里添加代码来手动处理输入框的文本删除逻辑 | |
// 比如手动删除输入框中的最后一个字符 | |
let currentValue = this.value; | |
this.value = currentValue.substring(0, currentValue.length - 1); | |
} | |
}); | |
//copy parse for apiKey | |
document | |
.getElementById('api-key-input') | |
.addEventListener('paste', function(event) { | |
event.preventDefault(); | |
event.stopPropagation(); | |
const text = event.clipboardData.getData('text/plain'); | |
document.getElementById('api-key-input').value = text; | |
}); | |
} | |
function saveApiKey() { | |
let apiKey = document.getElementById('api-key-input').value; | |
console.log('Saving API key:', apiKey); | |
//trim | |
apiKey = apiKey.trim(); | |
//check apiKey | |
if (apiKey) { | |
GM_setValue('apiKey', apiKey); | |
alert('API Key saved successfully!'); | |
} else { | |
alert('Please enter an API key.'); | |
} | |
} | |
// Function to search for images (placeholder function, implement your API call here) | |
function searchImages(query) { | |
console.log('Searching for:', query); | |
const apiKey = GM_getValue('apiKey', ''); | |
if (!apiKey) { | |
alert('Please enter an API key,by clicking the settings button.'); | |
return; | |
} | |
// search for images from giphy API | |
const url = `https://api.giphy.com/v1/gifs/search?api_key=${apiKey}&q=${encodeURIComponent( | |
query | |
)}&limit=20&rating=g&lang=zh-CN&bundle=messaging_non_clips`; | |
fetch(url) | |
.then(response => response.json()) | |
.then(data => { | |
console.log('API response:', data.data); | |
displayImages(data.data); | |
}); | |
} | |
// Function to display image results | |
function displayImages(images) { | |
const resultsContainer = document.getElementById('imageSearchResults'); | |
// resultsContainer remove all children | |
while (resultsContainer.firstChild) { | |
resultsContainer.removeChild(resultsContainer.firstChild); | |
} | |
resultsContainer.innerHTML = ''; // Clear previous results | |
// 对图片展示进行优化,增加过渡效果 | |
images.forEach(image => { | |
const imgElem = document.createElement('img'); | |
imgElem.src = image.images.original.url; | |
imgElem.style.width = '100px'; | |
imgElem.style.height = '100px'; | |
imgElem.style.margin = '5px'; | |
imgElem.style.borderRadius = '5px'; | |
imgElem.style.boxShadow = '0 2px 4px rgba(0,0,0,0.1)'; | |
imgElem.style.transition = 'transform 0.3s ease'; | |
imgElem.style.cursor = 'pointer'; | |
imgElem.title = 'Click to copy image URL'; | |
imgElem.addEventListener('mouseover', () => { | |
imgElem.style.transform = 'scale(1.1)'; | |
}); | |
imgElem.addEventListener('mouseout', () => { | |
imgElem.style.transform = 'scale(1)'; | |
}); | |
imgElem.addEventListener('click', () => { | |
GM_setClipboard(image.images.original.url); | |
// alert('Image URL copied to clipboard!'); | |
}); | |
resultsContainer.appendChild(imgElem); | |
}); | |
} | |
// when user click command + shift + i, create the search panel | |
document.addEventListener('keydown', function(event) { | |
if ( | |
(event.ctrlKey || event.metaKey) && | |
event.shiftKey && | |
event.code === 'KeyI' | |
) { | |
console.log('Search image clicked'); | |
createSearchPanel(); | |
} | |
}); | |
// press esc to close the search panel | |
document.addEventListener('keydown', function(event) { | |
if (event.key === 'Escape') { | |
document.getElementById('imageSearchPanel').remove(); | |
} | |
}); | |
// press enter to search | |
document.addEventListener('keydown', function(event) { | |
if (event.key === 'Enter') { | |
const query = document.getElementById('imageSearchQuery').value; | |
if (!query) { | |
return; | |
} | |
searchImages(query); | |
event.preventDefault(); | |
event.stopPropagation(); | |
// 阻止默认行为 | |
document.getElementById('imageSearchQuery').blur(); | |
} | |
}); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment