Monday, December 30, 2024

Building a browser extension

2024.12.18:

Started a new project! This time it's AI enabled browser extension. Although I have already launched two projects using the OpenAI API (SEO Meta Description AI and Novine.eu), plus one project that was abandoned, this is my first experience creating an extension.

Browser usage statistics suggest that I should start with a Chrome. However, as a Firefox user who is unwilling to switch my primary browser, I'll also develop the extension for Firefox in parallel.

To make the project more intriguing, I have decided to use JavaScript for the backend, which is also a new challenge for me. Previously I have developed backends only in PHP (during the time when PHP hosting was the most affordable), Java (since the launch of Google App Engine) and Python (since Google App Engine began supporting it).

Stay tuned, I hope this project will gross more than just peanuts. 😂 😭

2024.12.20:

✅ First backend version deployed
✅ Prototype extension developed for both Chrome and Firefox
✅ Did 81 push-ups

Time to conduct extensive tests, i.e., eat my own dog food.

2024.12.21:

✅ Came up with the extension icon.
✅ Decided to use MongoDB (another new technology for me).
✅ Implemented rudimentary user management.

Apparently, I have stepped into the ME.N of the MERN tech stack.

2024.12.22:

You are right, those corners were too sharp. Here is the smoothed version. 


Spent a day optimizing 45 lines of JavaScript code that were supposed to work in all circumstances, only to find out moments ago that all those lines can be replaced with:

document.execCommand("insertText", false, newText)

The catch: that call is deprecated.

2024.12.23:

✅ Deploying the database on MongoDB Atlas and connecting it to GoogleAppEngine.
✅ Adding cron jobs for user management.

2024.12.24:

✅ Implementing keyboard shortcuts for those who prefer not to click to open the context menu.

The shortcuts are Alt+Shift+P and Alt+Shift+I; you can start memorizing them. 🙂 It seems that’s it regarding the core functionality; what remains is the landing page and integration with a payment processor.

2024.12.26:

As I wrap up the landing page, it's time to dive deeper into UX/UI. Excited to share my chosen color palette! Check out this fantastic palette generator.

Updated palette = updated product icon.


And here is the price table! Major second typescale with WCAG AAA contrasts. My favorite contrast checker: https://webaim.org/resources/contrastchecker/

2024.12.29:

While testing on Windows and using Chrome instead of Chromium, I discovered that the shortcut Alt+Shift+I is reserved and it opens a feedback from. It's a pity since the letters P and I correspond to the first letters of my extension's actions.

Additionally, I found that the extension is not working properly in the Reddit markdown editor (it works fine in the default editor) and in Blogger.

2024.12.30:

I have decided to keep the existing keyboard shortcuts for Firefox and, in Chrome, replace Alt+Shift+I with Alt+Shift+O. It's right between I and P, and my action name contains that letter as well. For a moment, I considered using Alt+Shift+1 and Alt+Shift+2 instead, but they are more challenging to type. Ctrl+Alt combinations are not allowed, as stated in the Key combination requirements for Chrome. In any case, it was my mistake not to check the existing Chrome keyboard shortcuts and Mozilla keyboard shortcuts before deciding on mine.

The prompt still doesn't take the character limit for a particular social network into consideration, and sometimes it interprets questions as instructions. Asking ChatGPT to improve the prompt for its own API did not help.

2024.12.31:

I successfully implemented text replacement for both Blogger and Reddit. The main challenge with Blogger was that the editable text was contained within an iframe, while Reddit presented complexities due to multiple shadowRoot element chainings. Extensive testing is essential to ensure that no negative side effects have been introduced.

2025.01.02:

As shown in the video below, the browser extension displays error messages inside a modal dialog layered over the web page. CSS is loaded remotely, and perhaps I'll also use remotely loaded HTML and JavaScript to completely customize the dialog without requiring the user to update the already installed extension.


UX/UI Tip 1: When designing modals, always add all possible options to close them: click outside, click on the '×' button in the top right corner, click on a 'Close' button, and use the 'Esc' key as well.

UX/UI Tip 2: Restore the previous focus once your modal is closed.

2025.01.05

As I am finishing the product, I have just found out that a competitor launched an extension with quite similar functionality two days ago. They have a total of five users. My competitor's low user numbers are depressing me.

2025.01.09

Added semantic elements to HTML.
✅ Added essential documents: Terms of Service, Privacy Notice, and Refund Policy.
✅ Connected the custom domain to Google App Engine.
✅ Submitted the domain to the e-commerce provider for approval.

Sunday, December 29, 2024

My neovim configuration for python development (3)

In a lighthearted moment, I decided to experiment with Android devices for development. I installed Termux and Neovim, and I’d like to share my current configuration:

set encoding=utf-8
set number
syntax enable
set noswapfile
set backspace=indent,eol,start

set tabstop=4
set softtabstop=4
set shiftwidth=4
set expandtab
set autoindent
set fileformat=unix

set colorcolumn=80
highlight ColorColumn ctermbg=9

call plug#begin()

Plug 'catppuccin/nvim', { 'as': 'catppuccin' }
Plug 'morhetz/gruvbox'

Plug 'jiangmiao/auto-pairs'
Plug 'preservim/nerdtree'
Plug 'preservim/tagbar'
" Tagbar alternative
" Plug 'liuchengxu/vista.vim'
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
Plug 'sheerun/vim-polyglot'
Plug 'neoclide/coc.nvim', {'branch': 'release'}

call plug#end()

colorscheme catppuccin

" NERDTree
let NERDTreeQuitOnOpen=1
let g:NERDTreeMinimalUI=1
nmap <C-e> :NERDTreeToggle<CR>

" Tagbar
nmap <C-f> :TagbarToggle<CR>

" Tabs
let g:airline#extensions#tabline#enabled=1
let g:airline#extensions#tabline#fnamemode=':t'

nmap <C-PageUp> :bp<CR>
nmap <C-PageDown> :bn<CR>
nmap <C-w> :bd<CR>

" Autocomplete
inoremap <expr> <Tab> pumvisible() ? coc#_select_confirm() : "<Tab>"


Feel free to share your thoughts or any tips you might have for optimizing development on Android!


 



Wednesday, December 11, 2024

How to list PDF form field names using pyhton

Here’s a simple Python script that might come in handy. I used it for some experiments and am posting it here in case I need it again in the future. Feel free to use it as well!

import PyPDF2

# Open the PDF file
pdf_file = open("example.pdf", "rb")
pdf_reader = PyPDF2.PdfReader(pdf_file)

# Get the AcroFields
acro_fields = pdf_reader.get_fields()

print("Form Field Names:")
for field_name in acro_fields.keys():
print(f"- {field_name}")

# Close the PDF file
pdf_file.close()

PDF form field rename tools

Here’s a quick overview of some popular tools that can help you rename PDF form fields, ranging from free and simple to more advanced paid options.

Gavel PDF Unlocker and Field Renamer

A free, easy-to-use tool that doesn’t require any authentication. It automatically renames fields to match the word listed beside the field.

https://start.gavel.io/pdf

pdfFiller

It can rename form fields, but you need to create an account with them to use this feature. Once you've registered, you'll need to commit to at least a 30-day free trial in order to download your document, and you’ll be required to provide payment information. The cheapest plan starts at $8 per month.

https://www.pdffiller.com/

Try67 Tool Rename PDF Fields

This isn't a web app but a desktop Java application (Java must be installed). The tool costs $5 for the basic version, or $10 for the more advanced version. Alternatively, there's an Acrobat script available for $20.

https://www.try67.com/tool/easily-rename-pdf-fields


Let me know in the comments if I've missed any other tools!


Sunday, December 8, 2024

Software development on a touch phone (1)

I recently came across a guy with a GitHub repository boasting over 1.5K stars. His Neovim plugin is written and maintained entirely on Neovim. The punchline? He's developing on a touch phone because he doesn't own a computer—or even a physical keyboard! [1]

I found this inspirational, so I decided to try out development on a smartphone myself. Here's my "Hello, World!" in Python using Flask (video is at 4x speed). Later, I installed Neovim and ordered a Bluetooth keyboard.


[1] https://www.reddit.com/r/neovim/comments/1h7vhmg/bro_been_developing_his_2k_star_plugin_on_a/

Saturday, December 7, 2024

My neovim configuration for python development (2)

This Neovim configuration differs from the previous one, as it is optimized for a text terminal with limited colors (I couldn't find a suitable color scheme). The Python code completion plugin is compatible with Neovim version 0.7 (currently supported by Debian), and no plugins are used for split-screen terminal functionality.

" https://www.youtube.com/watch?v=wzrZPcwh-bE
 
set encoding=utf-8
set number
syntax enable
set noswapfile
set backspace=indent,eol,start

set tabstop=4
set softtabstop=4
set shiftwidth=4
set expandtab
set autoindent
set fileformat=unix

set colorcolumn=80
highlight ColorColumn ctermbg=9

call plug#begin()

Plug 'jiangmiao/auto-pairs'
Plug 'preservim/nerdtree'
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'

" https://www.youtube.com/watch?v=JWReY93Vl6g
Plug 'preservim/tagbar'

" https://jdhao.github.io/2018/12/24/centos_nvim_install_use_guide_en/#auto-completion-plugin-deoplete
Plug 'shougo/deoplete.nvim', { 'do': ':UpdateRemotePlugins' }
Plug 'zchee/deoplete-jedi'

call plug#end()

let g:airline_powerline_fonts=1
if !exists('g:airline_symbols')
    let g:airline_symbols = {}
endif

" NERDTree
let NERDTreeQuitOnOpen=1
let g:NERDTreeMinimalUI=1
nmap <F2> :NERDTreeToggle<CR>

" Tagbar
nmap <F3> :TagbarToggle<CR>

let g:deoplete#enable_at_startup = 1

" https://www.reddit.com/r/vim/comments/8n5bzs/comment/dzt3fix/
" Terminal Function
let g:term_buf = 0
let g:term_win = 0
function! TermToggle(height)
    if win_gotoid(g:term_win)
        hide
    else
        botright new
        exec "resize " . a:height
        try
            exec "buffer " . g:term_buf
        catch
            call termopen($SHELL, {"detach": 0})
            let g:term_buf = bufnr("")
            set nonumber
            set norelativenumber
            set signcolumn=no
        endtry
        startinsert!
        let g:term_win = win_getid()
    endif
endfunction

" Toggle terminal on/off (neovim)
nnoremap <F4> :call TermToggle(11)<CR>
inoremap <F4> <Esc>:call TermToggle(11)<CR>
tnoremap <F4> <C-\><C-n>:call TermToggle(11)<CR>

" Terminal go back to normal mode
tnoremap <Esc> <C-\><C-n>
tnoremap :q! <C-\><C-n>:q!<CR>