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

Feature #111: Translation History #113

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
TRACKING_ID=1234

build: deps
TRACKING_ID=$(TRACKING_ID) yarn build

deps: package.json
yarn install
24 changes: 23 additions & 1 deletion background.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import Options from './lib/options'
import trackEvent from './lib/tracking'
import { localStorage } from './lib/storage'
import { generateUrls, parseResponse } from './lib/apiClient.mjs'
import { recordTranslation, getTranslationHistory } from './lib/history'
import options from './lib/options'

const blockTimeoutMs = 30000 * 60
const browserAction = chrome[process.env.MANIFEST_V3 === 'true' ? 'action' : 'browserAction']
Expand Down Expand Up @@ -125,6 +127,10 @@ async function on_translation_response(data, word, tl, last_translation, isRever
Object.assign(last_translation, translation)
await localStorage.set('last_translation', last_translation)

if (await Options.store_translations()) {
recordTranslation(word, sl, tl, isReverseTranslate, data)
}

console.log('response: ', translation)
return translation
}
Expand All @@ -148,7 +154,7 @@ async function detectLanguage(request) {
async function contentScriptListener(request) {
const except_urls = await Options.except_urls()
const last_translation = await localStorage.get('last_translation') || {}

console.debug('contentScriptListener Invoked', request)
switch (request.handler) {
case 'get_last_tat_sl_tl':
console.log('get_last_tat_sl_tl')
Expand Down Expand Up @@ -205,6 +211,22 @@ async function contentScriptListener(request) {
await Options.disable_everywhere(0)
}
break
case 'exportTranslationHistory':
if (await options.store_translations()) {
let records = await getTranslationHistory()
let jsonRecords = JSON.stringify(records)
const blob = new Blob([jsonRecords], { type: 'application/json' })
const url = URL.createObjectURL(blob)

// Use the downloads API to save the file

browser.downloads.download({
url: url,
filename: 'translation_history.json',
saveAs: true // Prompts the user with the save dialog
})
}
break
default:
console.error('Unknown request', JSON.stringify(request, null, 2))
return {}
Expand Down
26 changes: 17 additions & 9 deletions contentscript.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import $ from 'jquery'
import {
renderError,
modifierKeys,
escape_html,
formatTranslation
} from './lib/transover_utils'
Expand All @@ -18,6 +17,7 @@ if (process.env.MANIFEST_V3 === 'true') {
let options
let disable_on_this_page
let disable_everywhere
let store_translations

function copyToClipboard(text) {
const input = document.createElement('input')
Expand Down Expand Up @@ -174,9 +174,11 @@ async function loadOptions() {

disable_on_this_page = ignoreThisPage(options)
disable_everywhere = options.disable_everywhere
store_translations = options.store_translations
chrome.runtime.sendMessage({
handler: 'setIcon',
disabled: disable_on_this_page || disable_everywhere
disabled: disable_on_this_page || disable_everywhere,
store_translations: store_translations
})
}

Expand All @@ -200,7 +202,7 @@ function processEvent(e) {
return res
}

function getExactTextNode(nodes, e) {
function getExactTextNode(_, e) {
$(text_nodes).wrap('<transblock />')
let hit_text_node = document.elementFromPoint(e.clientX, e.clientY)

Expand Down Expand Up @@ -388,7 +390,7 @@ function processEvent(e) {
}
}

function withOptionsSatisfied(e, do_stuff) {
function withOptionsSatisfied(_, do_stuff) {
if (!options) return

//respect 'translate only when alt pressed' option
Expand Down Expand Up @@ -464,7 +466,7 @@ function speak({ text, lang }) {
}

$(document).keydown(e => {
if (e.keyCode === 27) {
if (e.key === 'Escape') {
audio.pause()
audio.removeAttribute('src')
audio.load()
Expand All @@ -481,7 +483,7 @@ function speak({ text, lang }) {
$(document).keydown(function(e) {
if (!options) return

if (modifierKeys[e.keyCode] == options.popup_show_trigger) {
if (e.key == options.popup_show_trigger) {
show_popup_key_pressed = true

const selection = window.getSelection().toString()
Expand All @@ -505,7 +507,7 @@ $(document).keydown(function(e) {
}

// text-to-speech on ctrl press
if (!e.originalEvent.repeat && modifierKeys[e.keyCode] == options.tts_key && options.tts && $('transover-popup').length > 0) {
if (!e.originalEvent.repeat && e.key == options.tts_key && options.tts && $('transover-popup').length > 0) {
chrome.runtime.sendMessage({
handler: 'trackEvent',
event: {
Expand Down Expand Up @@ -538,11 +540,11 @@ $(document).keydown(function(e) {
}

// Hide tat popup on escape
if (e.keyCode == 27) {
if (e.key == 'Escape') {
removePopup('transover-type-and-translate-popup')
}
}).keyup(function(e) {
if (options && modifierKeys[e.keyCode] == options.popup_show_trigger) {
if (options && e.key == options.popup_show_trigger) {
show_popup_key_pressed = false
}
})
Expand Down Expand Up @@ -666,6 +668,12 @@ window.addEventListener('message', function(e) {
if (e.source != window)
return

if (e.data.type == 'exportTranslationHistory') {
chrome.runtime.sendMessage({
handler: 'exportTranslationHistory'
})
}

if (e.data.type == 'transoverTranslate') {
chrome.runtime.sendMessage({handler: 'translate', word: e.data.text, sl: e.data.sl, tl: e.data.tl}, function(response) {
debug('tat response: ', response)
Expand Down
42 changes: 42 additions & 0 deletions lib/history.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* eslint-disable no-console */
import Dexie from 'dexie'

const db = new Dexie('transover_db')

db.version(1).stores({
translations: '++id,word,source_language,target_language,reverse_translation,is_sentence,gt_resp,created_at'
})

function hasWhiteSpace(s) {
return /\s/g.test(s)
}

function isSentence(word) {
if (hasWhiteSpace(word) || word.length > 20) {
return true
}
return false
}

export async function recordTranslation(word, sl, tl, isReverseTranslate, gtResponse) {
console.debug('recordTranslation:', arguments)
let id = await db.translations.add({
word: word,
source_language: sl,
target_language: tl,
reverse_translation: isReverseTranslate,
is_sentence: isSentence(word),
gt_resp: gtResponse,
created_at: new Date().toISOString()
})

return id
}

export async function getTranslations() {
}


export async function getTranslationHistory() {
return await db.translations.toArray()
}
6 changes: 6 additions & 0 deletions lib/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,10 @@ export default {
}
return parseInt( await localStorage.get('disable_everywhere') ) || 0
},
store_translations: async function (arg) {
if (arg != undefined) {
return await localStorage.set('store_translations', arg)
}
return parseInt(await localStorage.get('store_translations')) || 1
},
}
7 changes: 4 additions & 3 deletions lib/options_script.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ async function save_options() {
await Options.do_not_show_oops($('#do_not_show_oops:checked').val() ? 1 : 0)
await Options.popup_show_trigger($('#word_key_only_key').val())
await Options.show_from_lang($('#show_from_lang:checked').val() ? 1 : 0)
await Options.store_translations($('#record:checked').val() ? 1 : 0)

$('.flash').fadeIn().delay(3000).fadeOut()
}
Expand Down Expand Up @@ -154,7 +155,7 @@ async function fill_reverse_lang() {
async function populate_popup_show_trigger() {
const saved_popup_show_trigger = await Options.popup_show_trigger()

;[...new Set(Object.values(modifierKeys))].forEach(function(key) {
modifierKeys.forEach(function(key) {
$('#word_key_only_key, #selection_key_only_key').each(function() {
$(this).append($('<option>', {value: key}).text(key).prop('selected', saved_popup_show_trigger == key))
})
Expand Down Expand Up @@ -223,7 +224,7 @@ async function load() {
$('#fontSize').val(await Options.fontSize())

$('#tts').attr('checked', await Options.tts() ? true : false)
;[...new Set(Object.values(modifierKeys))].forEach(async function(key) {
modifierKeys.forEach(async function(key) {
$('#tts_key').append($('<option>', {value: key}).text(key).prop('selected', await Options.tts_key() == key))
})

Expand All @@ -232,7 +233,7 @@ async function load() {

$('#save_button').click(function() { save_options() })
$(document).on('keydown', function(e) {
if (e.keyCode == 13) {
if (e.key === 'Enter') {
save_options()
}
})
Expand Down
1 change: 1 addition & 0 deletions lib/tat_popup.html
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
<div id="disable_on_this_page_container">
<label><input id="disable_on_this_page" type="checkbox"/>Disable on this site</label>
<label><input id="disable_everywhere" type="checkbox"/>Disable everywhere</label>
<label><button id="tat_history_export" >Export Translation History</button></label>
</div>
<a href="#" id="tat_close"></a>
</div>
Expand Down
5 changes: 5 additions & 0 deletions lib/tat_popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ class TatPopupTransover extends HTMLElement {
}
}

this.q('#tat_history_export').onclick = (e) => {
window.postMessage({type: 'exportTranslationHistory'}, '*')
e.preventDefault()
}

this.q('main').onkeydown = (e) => {
if (e.keyCode == 13) {
sendTranslate()
Expand Down
11 changes: 8 additions & 3 deletions lib/transover_utils.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { languages } from './languages'

export const modifierKeys = {
16: 'shift', 17: 'ctrl', 18: 'alt', 224: 'meta', 91: 'command', 93: 'command', 13: 'Return'
}
export const modifierKeys = new Set([
'Alt',
'Control',
'Enter',
'Escape',
'Meta',
'Shift'])


export function renderError (message) {
return `
Expand Down
1 change: 1 addition & 0 deletions manifest_v2.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
},
"permissions": [
"storage",
"downloads",
"https://translate.googleapis.com/*",
"https://clients5.google.com/*",
"https://www.google-analytics.com/*"
Expand Down
3 changes: 2 additions & 1 deletion manifest_v3.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
}
},
"permissions": [
"storage"
"storage",
"downloads"
],
"host_permissions": [
"https://translate.googleapis.com/*",
Expand Down
19 changes: 12 additions & 7 deletions options.html
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,17 @@ <h1>Configuration</h1>
</div>

<div class="option">
<input type="checkbox" id="tts" name="tts"/>
<label for="tts">Enable Text-To-Speech</label>
<label for="tts_key">when I press
<select name="tts_key" id="tts_key"></select>
while popup is showing
</label>
<input type="checkbox" id="record" name="record"/>
<label for="record">Record/Store Translated Words for Export</label>
</div>

<div class="option">
<input type="checkbox" id="tts" name="tts"/>
<label for="tts">Enable Text-To-Speech</label>
<label for="tts_key">when I press
<select name="tts_key" id="tts_key"></select>
while popup is showing
</label>
</div>

<div class="option">
Expand All @@ -162,7 +167,7 @@ <h1>Configuration</h1>
<div class="option">
<input type="checkbox" id="selection_key_only" name="selection_key_only"/>
<label for="selection_key_only">Only show selection translation when</label>
<label for="selection_key_only_key"> I hold the
<label for="selection_key_only_key"> I hold the
<select name="selection_key_only_key" id="selection_key_only_key"></select>
key</label>
</div>
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
},
"dependencies": {
"date-fns": "^2.29.3",
"dexie": "^4.0.9",
"jquery": "^3.6.3"
}
}