├── .gitignore ├── .nvmrc ├── README.md ├── design ├── README.md ├── gifs │ └── demo.gif ├── graphics.ai ├── graphics │ ├── graphics.ai │ ├── graphics_Large Icon.png │ ├── graphics_Large Promo Tile.png │ ├── graphics_Marquee Promo Tile.png │ ├── graphics_Medium Icon.png │ └── graphics_Small Promo Tile.png └── screenshots │ ├── base │ ├── screenshot 1.png │ ├── screenshot 2.png │ └── screenshot 3.png │ ├── screenshots.psd │ └── stylized │ ├── screenshot 1.png │ ├── screenshot 2.png │ └── screenshot 3.png ├── package-lock.json ├── package.json └── src ├── command-field.vue ├── command.vue ├── fonts └── Comfortaa-Regular.ttf ├── help.vue ├── manifest.json ├── popup ├── index.js ├── popup.html └── popup.vue ├── storage └── command.ts └── theme.scss /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | .cache/ 4 | .DS_STORE -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v11 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 |

6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |

16 | 17 | --- 18 | 19 | gata helps you find the information you need, quicker than ever. 20 | 21 | gata allows you to define dynamic shortcuts allowing you to jump to the page you need, when you need it. Just supply gata with a URL, define some variables, and you're done! 22 | 23 | Examples include: 24 | - Going to a Twitter profile 25 | - Jumping to a specific repository on Github 26 | - Viewing your favourite Reddit, sorted how you choose 27 | 28 | ## How does it work? 29 | 30 | To create a shortcut to go to a Twitter profile, we'll provide the URL "https://twitter.com/%s" 31 | 32 | The "%s" signifies a variable. This is the part that you are going to fill in when you access the shortcut. 33 | 34 | When you go to use this shortcut, gata will prompt you to enter the username you want to access and take you there. 35 | 36 | ## Features 37 | 38 | - Keyboard navigation - access all your shortcuts without using your mouse 39 | - Ctrl+. (⌘+. on Mac) to open 40 | - Once open, start typing to filter to the shortcut you want 41 | - Tab to expand the first result 42 | - Fill out form using keyboard 43 | - Enter to navigate to page 44 | - Syncing - your shortcuts are synced across Chrome browsers that are signed in with the same account 45 | 46 | ![](design/gifs/demo.gif) 47 | 48 | ## Screenshots 49 | 50 | |Viewing your shortcuts|Navigating to a shortcut|Creating a shortcut| 51 | |---|---|---| 52 | |![](design/screenshots/base/screenshot%201.png)|![](design/screenshots/base/screenshot%202.png)|![](design/screenshots/base/screenshot%203.png)| 53 | 54 | ## Contributing 55 | 56 | The following information is provided in order to contribute to this project: 57 | 58 | ### Setup 59 | 60 | The following will download, build, and install the extension in Chrome, allowing you to start developing. 61 | 62 | 1. Fork this repository and clone it to your local machine 63 | 1. Run `npm i` to install dependencies 64 | 1. Run `npm run build` to build 65 | 1. Go to `chrome://extensions` 66 | 1. Turn on "Developer Mode" in the top-right 67 | 1. Click "Load unpacked" 68 | 1. Navigate to the `dist` directory and select it 69 | 70 | Chrome will install the extension. After you make changes, run `npm run build` again and the extension should automatically update in Chrome. If not, just click the reload icon for gata on the extensions page. 71 | 72 | ### PRs 73 | 74 | After you have made your change, push your branch to your forked copy and make a pull request into this repo. Make sure to reference any issues you closing with your change. I will be sure to review your change and and it integrated. 75 | 76 | ## Technologies 77 | 78 | gata is built with: 79 | 80 | - [Vue.js](https://addons.cdn.mozilla.net/static/img/addons-buttons/AMO-button_1.png) 81 | - [Bulma](https://bulma.io/) 82 | - [Parcel](https://parceljs.org/) 83 | -------------------------------------------------------------------------------- /design/README.md: -------------------------------------------------------------------------------- 1 | # Graphics 2 | 3 | This file previews the graphics that have been created for gata. 4 | 5 | ## Promo Graphics 6 | 7 | These can be found in the `graphics/` directory. 8 | 9 | ### Small Promo Tile - 440x280 10 | 11 | ![](graphics/graphics_Small%20Promo%20Tile.png) 12 | 13 | ### Large Promo Tile - 920x680 14 | 15 | ![](graphics/graphics_Large%20Promo%20Tile.png) 16 | 17 | ### Marquee Promo Tile - 1400x560 18 | 19 | ![](graphics/graphics_Marquee%20Promo%20Tile.png) 20 | 21 | ### Icons 22 | 23 | |Icon Size|Icon| 24 | |---|---| 25 | |48x48|![](graphics/graphics_Medium%20Icon.png)| 26 | |129x129|![](graphics/graphics_Large%20Icon.png)| 27 | 28 | ## Screenshots 29 | 30 | These can be found in the `screenshots/stylized` and `screenshots/base` directories. 31 | 32 | ### Screenshot 1 - 1280x800 33 | 34 | |Base|Stylized| 35 | |---|---| 36 | |![](screenshots/base/screenshot%201.png)|![](screenshots/stylized/screenshot%201.png)| 37 | 38 | ### Screenshot 2 - 1280x800 39 | 40 | |Base|Stylized| 41 | |---|---| 42 | |![](screenshots/base/screenshot%202.png)|![](screenshots/stylized/screenshot%202.png)| 43 | 44 | 45 | ### Screenshot 3 - 1280x800 46 | 47 | |Base|Stylized| 48 | |---|---| 49 | |![](screenshots/base/screenshot%203.png)|![](screenshots/stylized/screenshot%203.png)| 50 | -------------------------------------------------------------------------------- /design/gifs/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evansalter/gata/de01a4ff0f9df94633e3ab7c929d121e6e21ae39/design/gifs/demo.gif -------------------------------------------------------------------------------- /design/graphics.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evansalter/gata/de01a4ff0f9df94633e3ab7c929d121e6e21ae39/design/graphics.ai -------------------------------------------------------------------------------- /design/graphics/graphics.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evansalter/gata/de01a4ff0f9df94633e3ab7c929d121e6e21ae39/design/graphics/graphics.ai -------------------------------------------------------------------------------- /design/graphics/graphics_Large Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evansalter/gata/de01a4ff0f9df94633e3ab7c929d121e6e21ae39/design/graphics/graphics_Large Icon.png -------------------------------------------------------------------------------- /design/graphics/graphics_Large Promo Tile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evansalter/gata/de01a4ff0f9df94633e3ab7c929d121e6e21ae39/design/graphics/graphics_Large Promo Tile.png -------------------------------------------------------------------------------- /design/graphics/graphics_Marquee Promo Tile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evansalter/gata/de01a4ff0f9df94633e3ab7c929d121e6e21ae39/design/graphics/graphics_Marquee Promo Tile.png -------------------------------------------------------------------------------- /design/graphics/graphics_Medium Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evansalter/gata/de01a4ff0f9df94633e3ab7c929d121e6e21ae39/design/graphics/graphics_Medium Icon.png -------------------------------------------------------------------------------- /design/graphics/graphics_Small Promo Tile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evansalter/gata/de01a4ff0f9df94633e3ab7c929d121e6e21ae39/design/graphics/graphics_Small Promo Tile.png -------------------------------------------------------------------------------- /design/screenshots/base/screenshot 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evansalter/gata/de01a4ff0f9df94633e3ab7c929d121e6e21ae39/design/screenshots/base/screenshot 1.png -------------------------------------------------------------------------------- /design/screenshots/base/screenshot 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evansalter/gata/de01a4ff0f9df94633e3ab7c929d121e6e21ae39/design/screenshots/base/screenshot 2.png -------------------------------------------------------------------------------- /design/screenshots/base/screenshot 3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evansalter/gata/de01a4ff0f9df94633e3ab7c929d121e6e21ae39/design/screenshots/base/screenshot 3.png -------------------------------------------------------------------------------- /design/screenshots/screenshots.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evansalter/gata/de01a4ff0f9df94633e3ab7c929d121e6e21ae39/design/screenshots/screenshots.psd -------------------------------------------------------------------------------- /design/screenshots/stylized/screenshot 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evansalter/gata/de01a4ff0f9df94633e3ab7c929d121e6e21ae39/design/screenshots/stylized/screenshot 1.png -------------------------------------------------------------------------------- /design/screenshots/stylized/screenshot 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evansalter/gata/de01a4ff0f9df94633e3ab7c929d121e6e21ae39/design/screenshots/stylized/screenshot 2.png -------------------------------------------------------------------------------- /design/screenshots/stylized/screenshot 3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evansalter/gata/de01a4ff0f9df94633e3ab7c929d121e6e21ae39/design/screenshots/stylized/screenshot 3.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gata", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "popup": "parcel popup/popup.html", 8 | "copy_files": "cp -f src/manifest.json design/graphics/*Icon.png dist", 9 | "build": "rm -rf dist/ && parcel build ./src/popup/popup.html && npm run copy_files", 10 | "zip_sources": "tar cf source_code.zip README.md package.json package-lock.json src design" 11 | }, 12 | "author": "", 13 | "license": "ISC", 14 | "dependencies": { 15 | "@mdi/font": "^4.8.95", 16 | "bulma": "^0.8.0", 17 | "fuse.js": "^3.4.6", 18 | "moment": "^2.24.0", 19 | "vue": "^2.6.11", 20 | "vue-class-component": "^7.2.2", 21 | "vue-hot-reload-api": "^2.3.4", 22 | "vue-property-decorator": "^8.3.0" 23 | }, 24 | "devDependencies": { 25 | "@types/chrome": "0.0.300", 26 | "@types/node": "^13.5.3", 27 | "@vue/component-compiler-utils": "^3.1.1", 28 | "parcel-bundler": "^1.12.4", 29 | "sass": "^1.25.0", 30 | "typescript": "^3.7.5", 31 | "vue-template-compiler": "^2.6.11" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/command-field.vue: -------------------------------------------------------------------------------- 1 | 50 | 51 | 100 | 101 | -------------------------------------------------------------------------------- /src/command.vue: -------------------------------------------------------------------------------- 1 | 70 | 71 | 164 | 165 | -------------------------------------------------------------------------------- /src/fonts/Comfortaa-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evansalter/gata/de01a4ff0f9df94633e3ab7c929d121e6e21ae39/src/fonts/Comfortaa-Regular.ttf -------------------------------------------------------------------------------- /src/help.vue: -------------------------------------------------------------------------------- 1 | 113 | 114 | 129 | 130 | -------------------------------------------------------------------------------- /src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gata", 3 | "version": "2.0.0", 4 | "description": "Bookmarks made better", 5 | "manifest_version": 3, 6 | "icons": { 7 | "128": "graphics_Large Icon.png", 8 | "48": "graphics_Medium Icon.png" 9 | }, 10 | "action": { 11 | "default_popup": "popup.html" 12 | }, 13 | "permissions": [ 14 | "storage" 15 | ], 16 | "commands": { 17 | "_execute_action": { 18 | "suggested_key": { 19 | "default": "Ctrl+Period" 20 | }, 21 | "description": "Opens the command palette" 22 | } 23 | }, 24 | "browser_specific_settings": { 25 | "gecko": { 26 | "id": "gata@evansalter.com", 27 | "strict_min_version": "58.0" 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/popup/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import Popup from './popup.vue'; 3 | import '@mdi/font/css/materialdesignicons.min.css'; 4 | 5 | Vue.directive('focus', { 6 | inserted: function(el) { 7 | el.focus(); 8 | } 9 | }); 10 | 11 | new Vue({ 12 | render: h => h(Popup), 13 | }).$mount("#popup"); -------------------------------------------------------------------------------- /src/popup/popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/popup/popup.vue: -------------------------------------------------------------------------------- 1 | 76 | 77 | 168 | 169 | -------------------------------------------------------------------------------- /src/storage/command.ts: -------------------------------------------------------------------------------- 1 | import moment from 'moment'; 2 | 3 | export enum FieldType { 4 | String = 0, 5 | Dropdown = 1, 6 | } 7 | 8 | export class DropdownValue { 9 | value: string; 10 | isDefault: boolean; 11 | 12 | constructor(); 13 | constructor(value: string); 14 | constructor(value?: string) { 15 | this.value = value; 16 | this.isDefault = false; 17 | } 18 | } 19 | 20 | export class Field { 21 | name: string; 22 | type: FieldType; 23 | dropdownValues?: DropdownValue[]; 24 | 25 | public static fromObject(obj: Object) { 26 | const f = new Field(); 27 | for (let key in obj) { 28 | if (obj.hasOwnProperty(key)) { 29 | f[key] = obj[key] 30 | } 31 | } 32 | f.type = f.type || FieldType.String; 33 | return f; 34 | } 35 | 36 | public validate() { 37 | if (!this.name) { 38 | throw new Error('Field name is required'); 39 | } 40 | } 41 | } 42 | 43 | export class Command { 44 | id: string; 45 | name: string; 46 | description?: string; 47 | url: string; 48 | fields: Field[]; 49 | 50 | created: string; 51 | 52 | constructor(); 53 | constructor(url: string, fields: Field[], name?: string, description?: string); 54 | constructor(url?: string, fields?: Field[], name?: string, description?: string) { 55 | this.name = name; 56 | this.url = url; 57 | this.fields = fields; 58 | this.description = description; 59 | 60 | const now = moment(); 61 | this.id = now.utc().unix().toString(); 62 | this.created = now.toISOString(); 63 | } 64 | 65 | public static fromObject(obj: Object) { 66 | const c = new Command(); 67 | for (let key in obj) { 68 | if (obj.hasOwnProperty(key)) { 69 | c[key] = obj[key] 70 | } 71 | } 72 | c.fields.forEach((f, idx) => c.fields[idx] = Field.fromObject(f)); 73 | return c; 74 | } 75 | 76 | private validate() { 77 | if (!this.url) { 78 | throw new Error('URL is required'); 79 | } 80 | if (!this.id) { 81 | throw new Error('Internal Error: ID is required'); 82 | } 83 | for (let field of this.fields) { 84 | field.validate(); 85 | } 86 | } 87 | 88 | public save(): void { 89 | this.validate() 90 | chrome.storage.sync.set({ 91 | [this.id]: this 92 | }).then(console.log); 93 | } 94 | 95 | public delete(): void { 96 | chrome.storage.sync.remove(this.id).then(console.log); 97 | } 98 | 99 | public static list(): Promise { 100 | return new Promise((resolve, reject) => { 101 | chrome.storage.sync.get().then(results => { 102 | resolve(Object.entries(results).map((v: [string, Command]) => Command.fromObject(v[1]))) 103 | }) 104 | }); 105 | } 106 | } -------------------------------------------------------------------------------- /src/theme.scss: -------------------------------------------------------------------------------- 1 | /** 2 | Override Bulma theme colors 3 | */ 4 | $background: #F9DEC9; 5 | $primary: #1F646D; 6 | $success: #06D6A0; 7 | $danger: #ED6A5A; --------------------------------------------------------------------------------