diff --git a/public/_locales/en/detailed_description.txt b/public/_locales/en/detailed_description.txt new file mode 100644 index 0000000..7182fc3 --- /dev/null +++ b/public/_locales/en/detailed_description.txt @@ -0,0 +1,18 @@ +Load a random page from your bookmarks! + +More and more bookmarks going unvisited? Use WebMark to stop that! If you have a lot of bookmarks to visit later at some point (read: "never"), move or copy them to WebMark folder using Chrome's built-in bookmark manager (Ctrl+Shift+O on Windows/Linux, ⌘+Option+B on Mac, or just chrome://bookmarks). You can also save them as you go by clicking the save button you see once you click on the WebMark icon on the top right. Then when you're bored and need something to read, click on the load button to see a random page from WebMark folder! + +Notes: +• You can rename or move the WebMark folder. However, we don't create a new one unless it is deleted. + +Features available: +• Save bookmarks to WebMark folder +• Load a random page from WebMark folder +• Choose whether a page is loaded in the current tab or a new tab + +Features coming: +• Use keyboard shortcuts to save and load bookmarks +• Delete from WebMark folder once you finish reading the page +• Open the webmark folder in bookmark manager + +If you have any questions, concerns, comments, or criticisms, please feel free to leave a review or reach us at strgzrs@googlegroups.com! diff --git a/public/_locales/en/screenshot1280x800.png b/public/_locales/en/screenshot1280x800.png new file mode 100644 index 0000000..cf138a8 Binary files /dev/null and b/public/_locales/en/screenshot1280x800.png differ diff --git a/public/_locales/ko/detailed_description.txt b/public/_locales/ko/detailed_description.txt new file mode 100644 index 0000000..5bb4bde --- /dev/null +++ b/public/_locales/ko/detailed_description.txt @@ -0,0 +1,14 @@ +북마크된 페이지를 랜덤으로 골라드려요! + +북마크만 해 두고 안 보는 건 이제 그만! '나중에 봐야지' 생각만 하고 가지 않은 페이지들이 있다면 웹마크 폴더로 옮겨 보세요. 윈도우/리눅스에선 Ctrl+Shift+O, 맥에선 ⌘+Option+B를 누르면 크롬 북마크 관리자가 열려요. (또는 주소창에 chrome://bookmarks 를 입력하고 이동할 수도 있어요.) 아니면 서핑하다가 나중에 읽고 싶은 페이지가 있으면 웹마크 버튼을 누르고 '저장하기'를 눌러 저장해 뒀다가, 심심할 때 웹마크 버튼 - '불러오기'를 눌러 웹마크 폴더 속 페이지를 무작위로 하나 띄울 수 있어요. + +참고 : +• 웹마크폴더를 이동하거나 폴더의 이름을 바꿔도 괜찮아요. + +기능 : +• 웹마크 폴더에 북마크 저장하기 +• 웹마크 폴더에서 무작위로 불러오기 +• 단축키를 통한 저장하기(Alt+S)/불러오기(Alt+Q) +• 현재 탭에서 열지 새 탭에서 열지 설정 + +피드백은 리뷰를 남기거나 이메일(strgzrs@googlegroups.com)로 주시면 감사하겠습니다! diff --git a/public/_locales/ko/screenshot1280x800.png b/public/_locales/ko/screenshot1280x800.png new file mode 100644 index 0000000..87996bb Binary files /dev/null and b/public/_locales/ko/screenshot1280x800.png differ diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index 6051fbc..0000000 Binary files a/public/favicon.ico and /dev/null differ diff --git a/public/images/GitHub-Mark-64px.png b/public/images/GitHub-Mark-64px.png deleted file mode 100644 index 182a1a3..0000000 Binary files a/public/images/GitHub-Mark-64px.png and /dev/null differ diff --git a/public/images/default.png b/public/images/default.png deleted file mode 100644 index 61e1596..0000000 Binary files a/public/images/default.png and /dev/null differ diff --git a/public/manifest.json b/public/manifest.json index 5b2186d..40bbd3a 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -7,11 +7,11 @@ "bookmarks", "notifications", "storage", - "tabs" + "activeTab" ], "browser_action": { "default_popup": "index.html", - "default_icon": "images/default.png" + "default_icon": "images/128.png" }, "background": { "scripts": [ diff --git a/src/App.css b/src/App.css deleted file mode 100644 index 4931613..0000000 --- a/src/App.css +++ /dev/null @@ -1,3 +0,0 @@ -.App { - text-align: center; -} diff --git a/src/App.test.tsx b/src/App.test.tsx deleted file mode 100644 index 89b4e71..0000000 --- a/src/App.test.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react'; -// import ReactDOM from 'react-dom'; -// import App from './App'; - -// it('renders without crashing', () => { -// const div = document.createElement('div'); -// ReactDOM.render(, div); -// ReactDOM.unmountComponentAtNode(div); -// }); diff --git a/src/App.tsx b/src/App.tsx deleted file mode 100644 index 0d611c8..0000000 --- a/src/App.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import React from 'react'; -// import './App.css'; - -// const App: React.FC = () => { -// return ( -//
-//
-// -//
-//
-// -//
-//
-// ); -// } - -// export default App; diff --git a/src/Option.tsx b/src/Option.tsx index 6d1a3b7..c1046f6 100644 --- a/src/Option.tsx +++ b/src/Option.tsx @@ -8,4 +8,3 @@ ReactDOM.render( , document.getElementById('root') as HTMLElement ); - diff --git a/src/background.ts b/src/background.ts index 9dd1322..b171de4 100644 --- a/src/background.ts +++ b/src/background.ts @@ -1,10 +1,10 @@ -import * as constants from './constants' +import { FOLDER_ID_KEY } from './constants' import { createWebmarkFolder, saveClicked, loadClicked } from './utils' chrome.runtime.onInstalled.addListener( () => { chrome.storage.sync.get( - [constants.FOLDER_ID_KEY], + [FOLDER_ID_KEY], (result) => { if (Object.keys(result).length === 0) { console.log('webmarkFolderId not found.'); @@ -12,14 +12,14 @@ chrome.runtime.onInstalled.addListener( } else { console.log('webmarkFolderId found.'); - let webmarkFolderId: string = result[constants.FOLDER_ID_KEY]; + let webmarkFolderId: string = result[FOLDER_ID_KEY]; chrome.bookmarks.get( webmarkFolderId, () => { if (chrome.runtime.lastError) { console.log('webmark folder not found.'); createWebmarkFolder(); - chrome.storage.sync.remove(constants.FOLDER_ID_KEY); + chrome.storage.sync.remove(FOLDER_ID_KEY); return; } console.log('webmark folder found.'); @@ -41,4 +41,3 @@ chrome.commands.onCommand.addListener( } } ); - diff --git a/src/components/Popup.tsx b/src/components/Popup.tsx index 805d6b8..d39e423 100644 --- a/src/components/Popup.tsx +++ b/src/components/Popup.tsx @@ -1,6 +1,6 @@ import * as React from "react"; import PopupButton from "./PopupButton"; -import * as constants from "../constants" +import { SAVE_BUTTON_TEXT, LOAD_BUTTON_TEXT } from "../constants" import ButtonGroup from 'react-bootstrap/ButtonGroup' class Popup extends React.Component { @@ -10,8 +10,8 @@ class Popup extends React.Component { render() { return ( - - + + ); } diff --git a/src/constants.ts b/src/constants.ts index 08bf2e5..3764741 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -24,4 +24,3 @@ export const OPTIONS_ABOUT_CARD_TITLE: string = chrome.i18n.getMessage('optionsA export const OPTIONS_ABOUT_VERSION_TITLE: string = chrome.i18n.getMessage('optionsAboutCardContentVersionTitle'); export const OPTIONS_ABOUT_TEAM_TITLE: string = chrome.i18n.getMessage('optionsAboutCardContentTeamNameTitle'); export const OPTIONS_ABOUT_HOMEPAGE_TITLE: string = chrome.i18n.getMessage('optionsAboutCardContentTeamLinkTitle'); - diff --git a/src/index.css b/src/index.css deleted file mode 100644 index ec2585e..0000000 --- a/src/index.css +++ /dev/null @@ -1,13 +0,0 @@ -body { - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', - 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', - sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -code { - font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', - monospace; -} diff --git a/src/index.tsx b/src/index.tsx index 83b26f7..653ec4a 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -2,15 +2,6 @@ import React from 'react'; import ReactDOM from 'react-dom'; import Popup from './components/Popup'; import { saveClicked, loadClicked } from './utils' -// import './index.css'; -// import * as serviceWorker from './serviceWorker'; - -// // If you want your app to work offline and load faster, you can change -// // unregister() to register() below. Note this comes with some pitfalls. -// // Learn more about service workers: https://bit.ly/CRA-PWA -// serviceWorker.unregister(); -// chrome.storage.sync.clear(); -// chrome.storage.sync.set({ [constants.LOAD_HERE_KEY]: true }); ReactDOM.render( , diff --git a/src/serviceWorker.ts b/src/serviceWorker.ts deleted file mode 100644 index 15d90cb..0000000 --- a/src/serviceWorker.ts +++ /dev/null @@ -1,143 +0,0 @@ -// This optional code is used to register a service worker. -// register() is not called by default. - -// This lets the app load faster on subsequent visits in production, and gives -// it offline capabilities. However, it also means that developers (and users) -// will only see deployed updates on subsequent visits to a page, after all the -// existing tabs open on the page have been closed, since previously cached -// resources are updated in the background. - -// To learn more about the benefits of this model and instructions on how to -// opt-in, read https://bit.ly/CRA-PWA - -const isLocalhost = Boolean( - window.location.hostname === 'localhost' || - // [::1] is the IPv6 localhost address. - window.location.hostname === '[::1]' || - // 127.0.0.1/8 is considered localhost for IPv4. - window.location.hostname.match( - /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ - ) -); - -type Config = { - onSuccess?: (registration: ServiceWorkerRegistration) => void; - onUpdate?: (registration: ServiceWorkerRegistration) => void; -}; - -export function register(config?: Config) { - if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { - // The URL constructor is available in all browsers that support SW. - const publicUrl = new URL( - (process as { env: { [key: string]: string } }).env.PUBLIC_URL, - window.location.href - ); - if (publicUrl.origin !== window.location.origin) { - // Our service worker won't work if PUBLIC_URL is on a different origin - // from what our page is served on. This might happen if a CDN is used to - // serve assets; see https://github.com/facebook/create-react-app/issues/2374 - return; - } - - window.addEventListener('load', () => { - const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; - - if (isLocalhost) { - // This is running on localhost. Let's check if a service worker still exists or not. - checkValidServiceWorker(swUrl, config); - - // Add some additional logging to localhost, pointing developers to the - // service worker/PWA documentation. - navigator.serviceWorker.ready.then(() => { - console.log( - 'This web app is being served cache-first by a service ' + - 'worker. To learn more, visit https://bit.ly/CRA-PWA' - ); - }); - } else { - // Is not localhost. Just register service worker - registerValidSW(swUrl, config); - } - }); - } -} - -function registerValidSW(swUrl: string, config?: Config) { - navigator.serviceWorker - .register(swUrl) - .then(registration => { - registration.onupdatefound = () => { - const installingWorker = registration.installing; - if (installingWorker == null) { - return; - } - installingWorker.onstatechange = () => { - if (installingWorker.state === 'installed') { - if (navigator.serviceWorker.controller) { - // At this point, the updated precached content has been fetched, - // but the previous service worker will still serve the older - // content until all client tabs are closed. - console.log( - 'New content is available and will be used when all ' + - 'tabs for this page are closed. See https://bit.ly/CRA-PWA.' - ); - - // Execute callback - if (config && config.onUpdate) { - config.onUpdate(registration); - } - } else { - // At this point, everything has been precached. - // It's the perfect time to display a - // "Content is cached for offline use." message. - console.log('Content is cached for offline use.'); - - // Execute callback - if (config && config.onSuccess) { - config.onSuccess(registration); - } - } - } - }; - }; - }) - .catch(error => { - console.error('Error during service worker registration:', error); - }); -} - -function checkValidServiceWorker(swUrl: string, config?: Config) { - // Check if the service worker can be found. If it can't reload the page. - fetch(swUrl) - .then(response => { - // Ensure service worker exists, and that we really are getting a JS file. - const contentType = response.headers.get('content-type'); - if ( - response.status === 404 || - (contentType != null && contentType.indexOf('javascript') === -1) - ) { - // No service worker found. Probably a different app. Reload the page. - navigator.serviceWorker.ready.then(registration => { - registration.unregister().then(() => { - window.location.reload(); - }); - }); - } else { - // Service worker found. Proceed as normal. - registerValidSW(swUrl, config); - } - }) - .catch(() => { - console.log( - 'No internet connection found. App is running in offline mode.' - ); - }); -} - -export function unregister() { - if ('serviceWorker' in navigator) { - navigator.serviceWorker.ready.then(registration => { - registration.unregister(); - }); - } -} diff --git a/src/utils.ts b/src/utils.ts index 954934d..f07f77e 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,9 +1,9 @@ /*global chrome*/ -import * as constants from './constants' +import { FOLDER_ID_KEY, FOLDER_EMPTY, FOLDER_NAME, PAGE_ALREADY_EXISTS, SAVE_SUCCESSFUL, LOAD_HERE_KEY } from './constants' export let saveClicked = (): void => { chrome.storage.sync.get( - [constants.FOLDER_ID_KEY], + [FOLDER_ID_KEY], function (result) { if (Object.keys(result).length === 0) { console.log('webmarkFolderId not found.'); @@ -11,14 +11,14 @@ export let saveClicked = (): void => { } else { console.log('webmarkFolderId found.'); - let webmarkFolderId: string = result![constants.FOLDER_ID_KEY]; + let webmarkFolderId: string = result![FOLDER_ID_KEY]; chrome.bookmarks.get( webmarkFolderId, function () { if (chrome.runtime.lastError) { console.log('webmark folder not found.'); createWebmarkFolder(saveClicked); - chrome.storage.sync.remove(constants.FOLDER_ID_KEY); + chrome.storage.sync.remove(FOLDER_ID_KEY); return; } console.log('webmark folder found.'); @@ -32,24 +32,24 @@ export let saveClicked = (): void => { export let loadClicked = (): void => { chrome.storage.sync.get( - [constants.FOLDER_ID_KEY], + [FOLDER_ID_KEY], function (result) { if (Object.keys(result).length === 0) { console.log('webmarkFolderId not found.'); createWebmarkFolder(); - showNotice(constants.FOLDER_EMPTY); + showNotice(FOLDER_EMPTY); return; } console.log('webmarkFolderId found.'); - let webmarkFolderId: string = result![constants.FOLDER_ID_KEY]; + let webmarkFolderId: string = result![FOLDER_ID_KEY]; chrome.bookmarks.get( webmarkFolderId, function () { if (chrome.runtime.lastError) { console.log('webmark folder not found.'); createWebmarkFolder(); - showNotice(constants.FOLDER_EMPTY); - chrome.storage.sync.remove(constants.FOLDER_ID_KEY); + showNotice(FOLDER_EMPTY); + chrome.storage.sync.remove(FOLDER_ID_KEY); return; } console.log('webmark folder found.'); @@ -63,12 +63,12 @@ export let loadClicked = (): void => { export let createWebmarkFolder = (callback?: () => void): void => { chrome.bookmarks.create( { - 'title': constants.FOLDER_NAME, + 'title': FOLDER_NAME, }, function (newFolder) { chrome.storage.sync.set( { - [constants.FOLDER_ID_KEY]: newFolder.id, + [FOLDER_ID_KEY]: newFolder.id, }, function () { console.log('set webmarkFolderId to ' + newFolder.id); if (callback !== undefined) { @@ -95,7 +95,7 @@ let isInTree = (url: string, nodes: chrome.bookmarks.BookmarkTreeNode[]): boolea while (nodes.length > 0) { let node: chrome.bookmarks.BookmarkTreeNode = nodes.pop()!; if (node.url) { // bookmark - if (node.url == url) { + if (node.url === url) { return true; } } else if (node.children) { // folder and has children @@ -112,7 +112,7 @@ let saveIfNotAlreadyThere = (webmarkFolderId: string, url: string, title: string webmarkFolderId, (results: chrome.bookmarks.BookmarkTreeNode[]): void => { if (isInTree(url, results)) { - showNotice(constants.PAGE_ALREADY_EXISTS); + showNotice(PAGE_ALREADY_EXISTS); } else { console.log('Same page not found in the folder.'); @@ -130,7 +130,7 @@ let saveWithConfidence = (webmarkFolderId: string, url: string, title: string): 'title': title, }, () => { - showNotice(constants.SAVE_SUCCESSFUL); + showNotice(SAVE_SUCCESSFUL); console.log(url + ' saved to folder.'); } ); @@ -144,8 +144,8 @@ let loadRandomUrlFromFolder = (webmarkFolderId: string): void => { for (let node of bookmarkTreeNodes) { recursiveUrlCollection(node, urlList); } - if (urlList.length == 0) { - showNotice(constants.FOLDER_EMPTY); + if (urlList.length === 0) { + showNotice(FOLDER_EMPTY); return; } let randomIndex: number = Math.floor(Math.random() * urlList.length); @@ -157,9 +157,9 @@ let loadRandomUrlFromFolder = (webmarkFolderId: string): void => { let loadPage = (url: string): void => { chrome.storage.sync.get( - [constants.LOAD_HERE_KEY], + [LOAD_HERE_KEY], (result) => { - if (Object.keys(result).length !== 0 && result![constants.LOAD_HERE_KEY]) { + if (Object.keys(result).length !== 0 && result![LOAD_HERE_KEY]) { loadInCurrentTab(url); } else { @@ -180,12 +180,12 @@ let recursiveUrlCollection = (bookmark: chrome.bookmarks.BookmarkTreeNode, urlLi } } -var showNotice = (title: string, message: string = ''): void => { +let showNotice = (title: string, message: string = ''): void => { chrome.notifications.create( // notificationId intentionally not sent { 'type': 'basic', // required - 'iconUrl': 'images/default.png', // required + 'iconUrl': 'images/128.png', // required 'title': title, // required 'message': message, // required 'eventTime': Date.now(), @@ -197,7 +197,7 @@ var showNotice = (title: string, message: string = ''): void => { console.log('Showed message ("' + title + '") to user.'); } -var loadInCurrentTab = (url: string): void => { +let loadInCurrentTab = (url: string): void => { chrome.tabs.update( { 'url': url, @@ -206,7 +206,7 @@ var loadInCurrentTab = (url: string): void => { console.log('Opened ' + url + ' in the current tab.'); } -var loadInNewTab = (url: string): void => { +let loadInNewTab = (url: string): void => { chrome.tabs.create( { 'url': url,