Title: [Script] Notas do Usuário
Post by: TryNinja on August 31, 2022, 04:36:27 PM
Pediram esse script lá no board gringo e também vou postar ele aqui. Ele adiciona uma opção de adicionar uma nota/descrição em cada usuário, que só pode ser vista localmente. É uma forma de lembrar detalhes de uma pessoal (i.e bem conhecida, amigável, já negociei, estou devendo X reais, etc...). Tópico original: https://bitcointalk.org/index.php?topic=5411599 https://talkimg.com/images/2023/05/14/blobbc21ff12c60cafe1.pnghttps://talkimg.com/images/2023/05/14/blobab76f2ddd1240a27.pnghttps://talkimg.com/images/2023/05/14/blob5f9d7265f8a4eda9.pngInstallation- Install Tampermonkey (https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo?hl=en) (Chrome, Brave...) or Greasymonkey (https://addons.mozilla.org/en-US/firefox/addon/greasemonkey/) (Firefox). - Add a new script and paste the code: // ==UserScript== // @name BitcoinTalk User Notes // @version 0.3 // @description Adds an note field to each user on BitcoinTalk // @author TryNinja // @match https://bitcointalk.org/* // @icon https://www.google.com/s2/favicons?sz=64&domain=bitcointalk.org // @grant GM.setValue // @grant GM.getValue // @grant GM_setValue // @grant GM_getValue // ==/UserScript==
const enableModal = 1;
(async function() { 'use strict';
const addStyle = (css) => { const style = document.getElementById("GM_addStyleBy8626") || (() => { const style = document.createElement('style'); style.id = "GM_addStyleBy8626"; document.head.appendChild(style); return style; })(); const sheet = style.sheet; sheet.insertRule(css, (sheet.rules || sheet.cssRules || []).length); }
if (enableModal) { addStyle(`.modal { position: fixed; width: 100vw; height: 100vh; top: 0; left: 0; display: flex; align-items: center; justify-content: center; }`);
addStyle(`.modal-bg { position: absolute; width: 100%; height: 100%; }`);
addStyle(`.modal-container { min-width: 30vh; border-radius: 10px; background: #fff; position: relative; padding: 10px; }`);
addStyle(`.modal-close { position: absolute; right: 15px; top: 15px; outline: none; appearance: none; color: red; background: none; border: 0px; font-weight: bold; cursor: pointer; }`); };
const getValue = typeof GM_getValue === 'undefined' ? GM.getValue : GM_getValue; const setValue = typeof GM_setValue === 'undefined' ? GM.setValue : GM_setValue;
const getParentNodeNth = (element, num) => { let parent = element; for (let i = 0; i < num; i++) { if (parent.parentNode) { parent = parent.parentNode; } } return parent; };
const getNotes = async () => { let notes; try { notes = JSON.parse(await getValue('notes') ?? '{}'); } catch (error) { notes = {}; }; return notes; };
const setNotes = async notes => { if (typeof notes === 'string') { try { JSON.parse(notes); await setValue('notes', notes); } catch (error) { console.error('Notes value is an invalid JSON format') }; } else if (typeof notes === 'object') { await setValue('notes', JSON.stringify(notes ?? {})); }; };
const getUserNote = async user => { const notes = await getNotes(); if (!notes) { return null; } return notes[user]; };
const setUserNote = async (user, note) => { const notes = await getNotes(); notes[user] = note; await setNotes(notes) };
const texts = { addNote: '<a style="cursor: pointer; font-weight: bold" href="javascript:;">📜 Add Note</a>', withNote: note => `<a style="cursor: pointer; font-weight: bold" href="javascript:;"><b>📜</b> ${note}</a>` };
const addNote = async (user, element) => { const note = prompt('Input the note (empty to remove):'); await setUserNote(user, note); if (note) { element.innerHTML = texts.withNote(note); } else if (note !== null) { element.innerHTML = texts.addNote; } };
const exportNotesToInput = async () => { const notesInput = document.querySelector('#notesInput'); const notesImportExportDiv = document.querySelector('#notesImportExportDiv'); const doneImportButton = document.querySelector('#doneImportButton'); const notes = await getNotes(); const notesJsonString = JSON.stringify(Object.keys(notes) .filter(user => notes[user]).reduce((obj, user) => ({...obj, [user]: notes[user]}), {}));
notesInput.value = notesJsonString; notesImportExportDiv.querySelector('span').innerText = 'Export (copy the code)'; notesImportExportDiv.style.display = 'flex'; doneImportButton.style.display = 'none'; };
const importNotesFromInput = async () => { const notesInput = document.querySelector('#notesInput'); const notesImportExportDiv = document.querySelector('#notesImportExportDiv'); const doneImportButton = document.querySelector('#doneImportButton');
notesInput.value = ''; notesImportExportDiv.querySelector('span').innerText = 'Import (paste the code)'; notesImportExportDiv.style.display = 'flex'; doneImportButton.style.display = 'inline-block'; };
const importNotesFromInputDone = async () => { const notesInput = document.querySelector('#notesInput'); const confirmImport = confirm('Are you sure you want to override your local notes?');
if (confirmImport && notesInput.value) { setNotes(notesInput.value); loadUserNotesList(); } };
const insertNotesModal = async () => { let notesModal = document.querySelector('#userNotesModal');
if (!notesModal) { const moreMenuBtn = document.querySelector('body'); notesModal = document.createElement('div');
notesModal.innerHTML = ` <div class="modal" id="modal-one"> <div class="modal-bg modal-exit"></div> <div class="modal-container"> <div style="margin-bottom: 5px;"> <b style="font-size: 2rem;">User Notes</b> <button class="modal-close modal-exit">X</button> </div>
<div style="display: flex; align-items: center; margin-bottom: 5px;"> <button id="exportUserNotes">Export</button> <button id="importUserNotes">Import</button> </div>
<div> <div style="display: none; flex-direction: column;" id="notesImportExportDiv"> <span id="notesInputText"></span> <input id="notesInput" /> <button id="doneImportButton" style="display: none;">Done</button> </div>
</div>
<div id="userNotesList" /> </div> </div>`; notesModal.classList.add('modal'); notesModal.style.visibility = 'hidden'; notesModal.setAttribute('id', 'userNotesModal');
moreMenuBtn.after(notesModal);
const exportButton = document.querySelector('#exportUserNotes'); const importButton = document.querySelector('#importUserNotes'); const doneImportButton = document.querySelector('#doneImportButton');
exportButton.addEventListener('click', () => exportNotesToInput()); importButton.addEventListener('click', () => importNotesFromInput()); doneImportButton.addEventListener('click', () => importNotesFromInputDone()); };
return notesModal; };
const loadUserNotesList = async () => { const userNotesList = document.querySelector('#userNotesList');
const notes = await getNotes();
if (Object.keys(notes).length) { userNotesList.innerHTML = Object.keys(notes) .filter(user => notes[user]) .map((user) => `<a href="https://bitcointalk.org/index.php?action=profile;u=${user}" target="_blank">${user}</a>: ${notes[user]}`).join('<br/>'); } else { userNotesList.innerHTML = 'No notes...'; }; };
const insertUserNotesMenuButton = async () => { let notesBtn = document.querySelector('#userNotesMenuBtn'); const modal = await insertNotesModal(); const modalExit = modal.querySelectorAll('.modal-exit');
if (!notesBtn) { const moreMenuBtn = document.querySelector(`a[href='/more.php']`).parentNode; notesBtn = document.createElement('td');
notesBtn.innerHTML = '<td><a href="javascript:;" id="openUserNotes">User Notes</a></td>'; notesBtn.classList.add('maintab_back'); notesBtn.setAttribute('id', 'userNotesMenuBtn'); moreMenuBtn.after(notesBtn);
const openUserNotes = document.querySelector('#openUserNotes') const notesImportExportDiv = document.querySelector('#notesImportExportDiv'); const notesInput = document.querySelector('#notesInput');
openUserNotes.addEventListener('click', () => { modal.style.visibility = 'visible'; modal.style.opacity = 1; notesImportExportDiv.style.display = 'none'; notesInput.value = ''; loadUserNotesList(); }); modalExit.forEach(el => el.addEventListener('click', () => { modal.style.visibility = 'hidden'; modal.style.opacity = 0; })); }
return notesBtn; };
if (enableModal) { insertNotesModal(); insertUserNotesMenuButton(); };
if (window.location.href.match(/topic=\d+/)) { const targets = [...document.querySelectorAll('td.poster_info div a:last-child')] .filter(e => window.getComputedStyle(getParentNodeNth(e, 11)).display !== 'none');
targets.map(async target => { const [_, userId] = [...target.parentNode.parentNode.childNodes].find(childNode => childNode.innerHTML).innerHTML.match(/u=(\d+)/); const noteDiv = document.createElement('div'); const note = await getUserNote(userId); if (!note) { noteDiv.innerHTML = texts.addNote; } else { noteDiv.innerHTML = texts.withNote(note); } target.before(noteDiv); noteDiv.addEventListener('click', () => addNote(userId, noteDiv), false); }); } else if (window.location.href.match(/profile;u=\d+/)) { const [_, userId] = window.location.href.match(/u=(\d+)/); const target = getParentNodeNth(document.querySelector('#bodyarea table tr td tbody tr:nth-child(2) tr:last-child').parentNode, 1); const noteDiv = document.createElement('div'); const note = await getUserNote(userId); if (!note) { noteDiv.innerHTML = texts.addNote; } else { noteDiv.innerHTML = texts.withNote(note); } target.before(noteDiv); noteDiv.addEventListener('click', () => addNote(userId, noteDiv), false); } })();
Title: Re: [Script] Notas do Usuário
Post by: joker_josue on August 31, 2022, 07:23:38 PM
Mas um excelente trabalho e contribuição para a comunidade! Obrigado! ;)
Não é que eu pessoalmente vá usar, pelos a primeira vista. Mas, não deixa de ser uma ferramenta com alguma utilidade.
Tens de criar uma lista dos teus scripts. ::)
Por falar disso, sei que existe mais vários scripts para o fórum. Onde é que eu os posso encontrar?
Title: Re: [Script] Notas do Usuário
Post by: TryNinja on August 31, 2022, 07:52:44 PM
Por falar disso, sei que existe mais vários scripts para o fórum. Onde é que eu os posso encontrar?
List of Bitcointalk.org Userscripts/ Add-ons (https://bitcointalk.org/index.php?topic=5148488.0) Eu uso os meus, o Enhanced merit UI (https://bitcointalk.org/index.php?topic=2833350.msg52249695#msg52249695), e para fazer o quote de posts em tópicos trancados (https://bitcointalk.org/index.php?topic=5226578.0). Também uso a extensão do BPIP (https://bitcointalk.org/index.php?topic=5224821.0) que tem várias adições do ninjastic.space. 8)
Title: Re: [Script] Notas do Usuário
Post by: joker_josue on August 31, 2022, 11:07:24 PM
Eu sou muito purista... não uso extensões nenhumas. 8) Uso o teu bot, mas não é nenhuma extensão. ::) Obrigado pelo link, pode ser que analise com mais detalhe esses extras e comece a usar algum. Eu uso os meus [...]
Era um pouco mau, criares extensões e depois não as usares. :P Nota: não dou mais merits pelo excelente trabalho, porque não tenho. :-\ Tenho ver se me inspiro e candidato-me a fonte de merit.
Title: Re: [Script] Notas do Usuário
Post by: alegotardo on September 01, 2022, 01:02:04 AM
Por falar disso, sei que existe mais vários scripts para o fórum. Onde é que eu os posso encontrar?
List of Bitcointalk.org Userscripts/ Add-ons (https://bitcointalk.org/index.php?topic=5148488.0) Eu uso os meus, o Enhanced merit UI (https://bitcointalk.org/index.php?topic=2833350.msg52249695#msg52249695), e para fazer o quote de posts em tópicos trancados (https://bitcointalk.org/index.php?topic=5226578.0). Também uso a extensão do BPIP (https://bitcointalk.org/index.php?topic=5224821.0) que tem várias adições do ninjastic.space. 8) Legal!!! O Enhanced merit é bastante útil, eu não entendo porque ainda não simplificaram o processo de envio de merits para que possa ser feito na mesma página (nativamente sem extensões), seria muito mais fácil... creio que a encrenca seja mais por compatibilidade com dispositivos móveis, que já é um problema para várias outras tarefas. Sobre as notas, uma dúvida... onde fica salvo as anotações, tem como fazer backup delas caso eu queira formatar o pc, reinstalar o navegador ou levar para outro local?
Title: Re: [Script] Notas do Usuário
Post by: TryNinja on September 01, 2022, 01:08:26 AM
Sobre as notas, uma dúvida... onde fica salvo as anotações, tem como fazer backup delas caso eu queira formatar o pc, reinstalar o navegador ou levar para outro local?
No update que postei hoje já dá para exportar e importar localmente (copiando e salvando um texto com suas notas). Vou melhorando o script com o tempo. 8)
|