1678576080
Invest your time easily
The working loop in the Pomodoro Technique is split into a 25-minute focus session and a 5-minute rest session. During a work session, the user focuses on one todo item and should not do anything irrelevant. The Pomodoro Technique can greatly improve the efficiency of work and study and alleviate work fatigue.
In the Pomodoro Logger, the app will record the names and titles of the apps you use on your PC during the working sessions. The titles of apps contain rich semantic information. For example, the browser title includes the title of the website being viewed, and the IDE often provides the project path or project name.
Pomodoro Technique - Wikipedia - Google Chrome
DeepMind (@DeepMindAI) | Twitter - Google Chrome
pomodoro-logger [C:\code\pomodoro-logger] .\src\renderer\components\src\Application.tsx - WebStorm
By connecting your todo items with the corresponding recorded Pomodoro sessions, you can analyze how often you are interrupted by email and social software, the time distribution of the application and application title used to complete the task. It will help you have a more comprehensive understanding of your working hours on PC.
Pomodoro Logger keeps a list of distracting app (you can config it in the setting). When it detect your using distracting apps, you lose your efficiency.
It calculates user efficiency by a heuristic method.
Demonstrating your efficiency by the dots. The larger the hole, the less efficient you are.
You can view the record in detail by clicking the circle
Data 📈
Pomodoro Logger records your desktop activities when you are in a working session of Pomodoro.
It only records your application activities, including the name and title of the focused application.
You can import / export / delete all your data in the settings.
All the data is saved and processed locally.
Kanban Board
Pomodoro Logger has integrated Kanban Board to help you organize and estimate the time spent of your todos easily with confidence.
The lists in Kanban are divided into Todo
, In Progress
, and Done
. Though lists customization is possible, you are required to preserve In Progress
list and Done
list in order to track, estimate and analyze your project time spent. You can set the estimated time cost on each todo card. Pomodoro Logger will assist you with the corresponding actual time spent record. i.e., When you are focusing on a Kanban board, it will automatically associate your Pomodoro session with the todo cards of In Progress
list in the Kanban, which makes further analysis possible.
To make the statistics more accurate, you can keep the cards of the In Progress
list as few as possible to precisely reflect the tasks you are focusing on.
Download
Win10 / macOS / Linux
To download, go to release page.
Contribution
I'd love to see you're involved! Read the Contribution Guide for detail.
Screenshot
Pomodoro | Show Countdown in Tray |
---|---|
![]() | ![]() |
Session Finished | Switch Mode |
![]() | ![]() |
Kanban Board | Draggable Card |
---|---|
![]() | ![]() |
Estimate Your Time Spent | Search Your Cards |
![]() | ![]() |
Visulization |
---|
![]() |
![]() |
Author: zxch3n
Source Code: https://github.com/zxch3n/PomodoroLogger
License: GPL-3.0 license
1677692640
Antares is an SQL client based on Electron.js and Vue.js that aims to become a useful tool, especially for developers.
Our target is to support as many databases as possible, and all major operating systems, including the ARM versions.
At the moment this application is in development state, many features will come in future updates, and supports only MySQL/MariaDB, PostgreSQL, SQLite and Firebird SQL.
However, there are all the features necessary to have a pleasant database management experience, so give it a chance and send us your feedback, we would really appreciate it.
We are actively working on it, hoping to provide new cool features, improvements and fixes as soon as possible.
🔗 If you are curious to try Antares you can download and install the latest release.
👁 To stay tuned for new releases follow Antares SQL on Twitter.
🌟 Don't forget to leave a star if you appreciate this project.
🗳️ Poll: Which is the main OS you use Antares on?
Why are we developing an SQL client when there are a lot of them on the market?
The main goal is to develop a forever 100% free (without paid premium feature), full featured, as possible community driven, cross platform and open source alternative, empowered by JavaScript ecosystem.
A modern application created with minimalism and simplicity in mind, with features in the right places, not hundreds of tiny buttons, nested tabs or submenues; productivity comes first.
Based on your operating system you can have one or more distribution formats to choose based on your preferences.
Since Antares SQL is a free software we don't have a budget to spend on annual licenses or certificates. This can result that on some platforms you might need to put in some additional work to install this app.
On Linux you can simply download and run the .AppImage
distribution, install from Snap Store, from AUR or from our PPA repository.
On Windows you can choose between downloading the app from Microsoft Store or downloading the .exe
from our website or this github repo. Distributions that are not from Microsoft Store are not signed with a certificate, so to install you need to click on "More info" and then "Run anyway" on SmartScreen prompt.
On macOS you can run .dmg
distribution following this guide to install apps from unknown developers.
This is a roadmap with major features will come in near future.
Author: Antares-sql
Source Code: https://github.com/antares-sql/antares
License: MIT license
#typescript #javascript #electron #mysql #desktopapp #client
1675077547
ChatGPT Desktop Application (Mac, Windows and Linux)
ChatGPT_0.10.1_x64_en-US.msi: Direct download installer
Use winget:
# install the latest version
winget install --id=lencx.ChatGPT -e
# install the specified version
winget install --id=lencx.ChatGPT -e --version 0.10.0
Note: If the installation path and application name are the same, it will lead to conflict (#142)
.app
installerbrew tap lencx/chatgpt https://github.com/lencx/ChatGPT.git
brew install --cask chatgpt --no-quarantine
repo = "lencx/chatgpt"
tap repo, "https://github.com/#{repo}.git"
cask "chatgpt", args: { "no-quarantine": true }
.deb
installer, advantage small size, disadvantage poor compatibility.deb
fails to runchatgpt-desktop-bin
, and you can use your favourite AUR package manager to install it.This is a major and exciting update. It works like a Telegram bot command
and helps you quickly populate custom models to make chatgpt work the way you want it to. This project has taken a lot of my spare time, so if it helps you, please help spread the word or star it would be a great encouragement to me. I hope I can keep updating it and adding more interesting features.
You can look at awesome-chatgpt-prompts to find interesting features to import into the app. You can also use Sync Prompts
to sync all in one click, and if you don't want certain prompts to appear in your slash commands, you can disable them.
/
to bring up the command prompt, press the spacebar, and it will fill the input area with the text associated with the command by default (note: if it contains multiple command prompts, it will only select the first one as the fill, you can keep typing until the first prompted command is the one you want, then press the spacebar.{q}
tag (only single changes are supported #54). Use the keyboard ⇧
(arrow up) and ⇩
(arrow down) keys to select the slash command.
macOS
Linux
Windows
Theme
- Light
, Dark
, System
(Only macOS and Windows are supported).Stay On Top
: The window is stay on top of other windows.Titlebar
: Whether to display the titlebar, supported by macOS only.Hide Dock Icon
(#35): Hide application icons from the Dock(support macOS only).Show Dock Icon
in the menu item to re-display the application icon in the Dock (SystemTrayMenu -> Show Dock Icon
).Inject Script
: Using scripts to modify pages.Control Center
: The control center of ChatGPT application, it will give unlimited imagination to the application.Theme
, Stay On Top
, Titlebar
, ...User Agent
(#17): Custom user agent
, which may be required in some scenarios. The default value is the empty string.Switch Origin
(#14): Switch the site source address, the default is https://chat.openai.com
, please make sure the mirror site UI is the same as the original address. Otherwise, some functions may not be available.Go to Config
: Open the configuration file directory (path: ~/.chatgpt/*
).Clear Config
: Clear the configuration file (path: ~/.chatgpt/*
), dangerous operation, please backup the data in advance.Restart ChatGPT
: Restart the application, for example: the program is stuck or the injection script can take effect by restarting the application after editing.Awesome ChatGPT
: Recommended Related Resources.Undo
, Redo
, Cut
, Copy
, SelectAll
, ...Go Back
, Go Forward
, Scroll to Top of Screen
, Scroll to Bottom of Screen
, Refresh the Screen
, ...Update Log
: ChatGPT changelog.Report Bug
: Report a bug or give feedback.Toggle Developer Tools
: Developer debugging tools.Platform | Path |
---|---|
Linux | /home/lencx/.chatgpt |
macOS | /Users/lencx/.chatgpt |
Windows | C:\Users\lencx\.chatgpt |
[.chatgpt]
- application configuration root folderchat.conf.json
- preferences configurationchat.awesome.json
- Custom URL lists, similar to browser bookmarks. Any URL can be used as the main window or tray window (Control Conter -> Awesome)chat.model.json
- prompts configuration,contains three parts:user_custom
- Requires manual data entry (Control Conter -> Language Model -> User Custom)sync_prompts
- Synchronizing data from f/awesome-chatgpt-prompts (Control Conter -> Language Model -> Sync Prompts)sync_custom
- Synchronize custom json and csv file data, support local and remote (Control Conter -> Language Model -> Sync Custom)chat.model.cmd.json
- filtered (whether to enable) and sorted slash commands[cache_model]
- caching model datachatgpt_prompts.json
- Cache sync_prompts
datauser_custom.json
- Cache user_custom
dataae6cf32a6f8541b499d6bfe549dbfca3.json
- Randomly generated file names, cache sync_custom
data4f695d3cfbf8491e9b1f3fab6d85715c.json
- Randomly generated file names, cache sync_custom
databd1b96f15a1644f7bd647cc53073ff8f.json
- Randomly generated file names, cache sync_custom
dataCurrently, only json and csv are supported for synchronizing custom files, and the following formats need to be met, otherwise the application will be abnormal:
JSON format:
[
{
"cmd": "a",
"act": "aa",
"prompt": "aaa aaa aaa"
},
{
"cmd": "b",
"act": "bb",
"prompt": "bbb bbb bbb"
}
]
CSV format
"cmd","act","prompt"
"a","aa","aaa aaa aaa"
"b","bb","bbb bbb bbb"
Control Center
enhancementPop-up Search
enhancementIf you cannot open the application after the upgrade, please try to clear the configuration file, which is in the ~/.chatgpt/*
directory.
If you have already logged in in the main window, but the system tray window shows that you are not logged in, you can fix it by restarting the application (Menu -> Preferences -> Restart ChatGPT
).
It's safe, just a wrapper for OpenAI ChatGPT website, no other data transfer exists (you can check the source code).
# step1:
git clone https://github.com/lencx/ChatGPT.git
# step2:
cd ChatGPT
# step3: install deps
yarn
# step4:
yarn dev
# step5:
# bundle path: src-tauri/target/release/bundle
yarn build
Author: lencx
Source Code: https://github.com/lencx/ChatGPT
License: Apache-2.0 license
1666635180
Thanks to go-astilectron
build cross platform GUI apps with GO and HTML/JS/CSS. It is the official GO bindings of astilectron and is powered by Electron.
Demo
To see a minimal Astilectron app, checkout out the demo.
It uses the bootstrap and the bundler.
If you're looking for a minimalistic example, run go run example/main.go -v
.
Real-life examples
Here's a list of awesome projects using go-astilectron
(if you're using go-astilectron
and want your project to be listed here please submit a PR):
Bootstrap
For convenience purposes, a bootstrap has been implemented.
The bootstrap allows you to quickly create a one-window application.
There's no obligation to use it, but it's strongly recommended.
If you decide to use it, read thoroughly the documentation as you'll have to structure your project in a specific way.
Bundler
Still for convenience purposes, a bundler has been implemented.
The bundler allows you to bundle your app for every os/arch combinations and get a nice set of files to send your users.
Quick start
WARNING: the code below doesn't handle errors for readibility purposes. However you SHOULD!
go-astilectron
To import go-astilectron
run:
$ go get -u github.com/asticode/go-astilectron
go-astilectron
// Initialize astilectron
var a, _ = astilectron.New(log.New(os.Stderr, "", 0), astilectron.Options{
AppName: "<your app name>",
AppIconDefaultPath: "<your .png icon>", // If path is relative, it must be relative to the data directory
AppIconDarwinPath: "<your .icns icon>", // Same here
BaseDirectoryPath: "<where you want the provisioner to install the dependencies>",
VersionAstilectron: "<version of Astilectron to utilize such as `0.33.0`>",
VersionElectron: "<version of Electron to utilize such as `4.0.1` | `6.1.2`>",
})
defer a.Close()
// Start astilectron
a.Start()
// Blocking pattern
a.Wait()
For everything to work properly we need to fetch 2 dependencies : astilectron and Electron. .Start()
takes care of it by downloading the sources and setting them up properly.
In case you want to embed the sources in the binary to keep a unique binary you can use the NewDisembedderProvisioner function to get the proper Provisioner and attach it to go-astilectron
with .SetProvisioner(p Provisioner)
. Or you can use the bootstrap and the bundler. Check out the demo to see how to use them.
Beware when trying to add your own app icon as you'll need 2 icons : one compatible with MacOSX (.icns) and one compatible with the rest (.png for instance).
If no BaseDirectoryPath is provided, it defaults to the executable's directory path.
The majority of methods are asynchronous which means that when executing them go-astilectron
will block until it receives a specific Electron event or until the overall context is cancelled. This is the case of .Start()
which will block until it receives the app.event.ready
astilectron
event or until the overall context is cancelled.
NB! All paths in HTML (and Javascript) must be relative, otherwise the files will not be found. To make this happen in React for example, just set the homepage property of your package.json to "./".
{ "homepage": "./" }
// Create a new window
var w, _ = a.NewWindow("http://127.0.0.1:4000", &astilectron.WindowOptions{
Center: astikit.BoolPtr(true),
Height: astikit.IntPtr(600),
Width: astikit.IntPtr(600),
})
w.Create()
When creating a window you need to indicate a URL as well as options such as position, size, etc.
This is pretty straightforward except the astilectron.Ptr*
methods so let me explain: GO doesn't do optional fields when json encoding unless you use pointers whereas Electron does handle optional fields. Therefore I added helper methods to convert int, bool and string into pointers and used pointers in structs sent to Electron.
When developing in JS, it's very convenient to debug your code using the browser window's dev tools:
// Open dev tools
w.OpenDevTools()
// Close dev tools
w.CloseDevTools()
// Add a listener on Astilectron
a.On(astilectron.EventNameAppCrash, func(e astilectron.Event) (deleteListener bool) {
log.Println("App has crashed")
return
})
// Add a listener on the window
w.On(astilectron.EventNameWindowEventResize, func(e astilectron.Event) (deleteListener bool) {
log.Println("Window resized")
return
})
Nothing much to say here either except that you can add listeners to Astilectron as well.
// Play with the window
w.Resize(200, 200)
time.Sleep(time.Second)
w.Maximize()
Check out the Window doc for a list of all exported methods
// This will wait for the astilectron namespace to be ready
document.addEventListener('astilectron-ready', function() {
// This will listen to messages sent by GO
astilectron.onMessage(function(message) {
// Process message
if (message === "hello") {
return "world";
}
});
})
// This will send a message and execute a callback
// Callbacks are optional
w.SendMessage("hello", func(m *astilectron.EventMessage) {
// Unmarshal
var s string
m.Unmarshal(&s)
// Process message
log.Printf("received %s\n", s)
})
This will print received world
in the GO output
// This will listen to messages sent by Javascript
w.OnMessage(func(m *astilectron.EventMessage) interface{} {
// Unmarshal
var s string
m.Unmarshal(&s)
// Process message
if s == "hello" {
return "world"
}
return nil
})
// This will wait for the astilectron namespace to be ready
document.addEventListener('astilectron-ready', function() {
// This will send a message to GO
astilectron.sendMessage("hello", function(message) {
console.log("received " + message)
});
})
This will print "received world" in the Javascript output
// Clear window's HTTP cache
w.Session.ClearCache()
// If several displays, move the window to the second display
var displays = a.Displays()
if len(displays) > 1 {
time.Sleep(time.Second)
w.MoveInDisplay(displays[1], 50, 50)
}
// Init a new app menu
// You can do the same thing with a window
var m = a.NewMenu([]*astilectron.MenuItemOptions{
{
Label: astikit.StrPtr("Separator"),
SubMenu: []*astilectron.MenuItemOptions{
{Label: astikit.StrPtr("Normal 1")},
{
Label: astikit.StrPtr("Normal 2"),
OnClick: func(e astilectron.Event) (deleteListener bool) {
log.Println("Normal 2 item has been clicked")
return
},
},
{Type: astilectron.MenuItemTypeSeparator},
{Label: astikit.StrPtr("Normal 3")},
},
},
{
Label: astikit.StrPtr("Checkbox"),
SubMenu: []*astilectron.MenuItemOptions{
{Checked: astikit.BoolPtr(true), Label: astikit.StrPtr("Checkbox 1"), Type: astilectron.MenuItemTypeCheckbox},
{Label: astikit.StrPtr("Checkbox 2"), Type: astilectron.MenuItemTypeCheckbox},
{Label: astikit.StrPtr("Checkbox 3"), Type: astilectron.MenuItemTypeCheckbox},
},
},
{
Label: astikit.StrPtr("Radio"),
SubMenu: []*astilectron.MenuItemOptions{
{Checked: astikit.BoolPtr(true), Label: astikit.StrPtr("Radio 1"), Type: astilectron.MenuItemTypeRadio},
{Label: astikit.StrPtr("Radio 2"), Type: astilectron.MenuItemTypeRadio},
{Label: astikit.StrPtr("Radio 3"), Type: astilectron.MenuItemTypeRadio},
},
},
{
Label: astikit.StrPtr("Roles"),
SubMenu: []*astilectron.MenuItemOptions{
{Label: astikit.StrPtr("Minimize"), Role: astilectron.MenuItemRoleMinimize},
{Label: astikit.StrPtr("Close"), Role: astilectron.MenuItemRoleClose},
},
},
})
// Retrieve a menu item
// This will retrieve the "Checkbox 1" item
mi, _ := m.Item(1, 0)
// Add listener manually
// An OnClick listener has already been added in the options directly for another menu item
mi.On(astilectron.EventNameMenuItemEventClicked, func(e astilectron.Event) bool {
log.Printf("Menu item has been clicked. 'Checked' status is now %t\n", *e.MenuItemOptions.Checked)
return false
})
// Create the menu
m.Create()
// Manipulate a menu item
mi.SetChecked(true)
// Init a new menu item
var ni = m.NewItem(&astilectron.MenuItemOptions{
Label: astikit.StrPtr("Inserted"),
SubMenu: []*astilectron.MenuItemOptions{
{Label: astikit.StrPtr("Inserted 1")},
{Label: astikit.StrPtr("Inserted 2")},
},
})
// Insert the menu item at position "1"
m.Insert(1, ni)
// Fetch a sub menu
s, _ := m.SubMenu(0)
// Init a new menu item
ni = s.NewItem(&astilectron.MenuItemOptions{
Label: astikit.StrPtr("Appended"),
SubMenu: []*astilectron.MenuItemOptions{
{Label: astikit.StrPtr("Appended 1")},
{Label: astikit.StrPtr("Appended 2")},
},
})
// Append menu item dynamically
s.Append(ni)
// Pop up sub menu as a context menu
s.Popup(&astilectron.MenuPopupOptions{PositionOptions: astilectron.PositionOptions{X: astikit.IntPtr(50), Y: astikit.IntPtr(50)}})
// Close popup
s.ClosePopup()
// Destroy the menu
m.Destroy()
A few things to know:
go-astilectron
won't be able to capture its click event// New tray
var t = a.NewTray(&astilectron.TrayOptions{
Image: astikit.StrPtr("/path/to/image.png"),
Tooltip: astikit.StrPtr("Tray's tooltip"),
})
// Create tray
t.Create()
// New tray menu
var m = t.NewMenu([]*astilectron.MenuItemOptions{
{
Label: astikit.StrPtr("Root 1"),
SubMenu: []*astilectron.MenuItemOptions{
{Label: astikit.StrPtr("Item 1")},
{Label: astikit.StrPtr("Item 2")},
{Type: astilectron.MenuItemTypeSeparator},
{Label: astikit.StrPtr("Item 3")},
},
},
{
Label: astikit.StrPtr("Root 2"),
SubMenu: []*astilectron.MenuItemOptions{
{Label: astikit.StrPtr("Item 1")},
{Label: astikit.StrPtr("Item 2")},
},
},
})
// Create the menu
m.Create()
// Change tray's image
time.Sleep(time.Second)
t.SetImage("/path/to/image-2.png")
// Create the notification
var n = a.NewNotification(&astilectron.NotificationOptions{
Body: "My Body",
HasReply: astikit.BoolPtr(true), // Only MacOSX
Icon: "/path/to/icon",
ReplyPlaceholder: "type your reply here", // Only MacOSX
Title: "My title",
})
// Add listeners
n.On(astilectron.EventNameNotificationEventClicked, func(e astilectron.Event) (deleteListener bool) {
log.Println("the notification has been clicked!")
return
})
// Only for MacOSX
n.On(astilectron.EventNameNotificationEventReplied, func(e astilectron.Event) (deleteListener bool) {
log.Printf("the user has replied to the notification: %s\n", e.Reply)
return
})
// Create notification
n.Create()
// Show notification
n.Show()
// Get the dock
var d = a.Dock()
// Hide and show the dock
d.Hide()
d.Show()
// Make the Dock bounce
id, _ := d.Bounce(astilectron.DockBounceTypeCritical)
// Cancel the bounce
d.CancelBounce(id)
// Update badge and icon
d.SetBadge("test")
d.SetIcon("/path/to/icon")
// New dock menu
var m = d.NewMenu([]*astilectron.MenuItemOptions{
{
Label: astikit.StrPtr("Root 1"),
SubMenu: []*astilectron.MenuItemOptions{
{Label: astikit.StrPtr("Item 1")},
{Label: astikit.StrPtr("Item 2")},
{Type: astilectron.MenuItemTypeSeparator},
{Label: astikit.StrPtr("Item 3")},
},
},
{
Label: astikit.StrPtr("Root 2"),
SubMenu: []*astilectron.MenuItemOptions{
{Label: astikit.StrPtr("Item 1")},
{Label: astikit.StrPtr("Item 2")},
},
},
})
// Create the menu
m.Create()
Add the following line at the top of your javascript file :
const { dialog } = require('electron').remote
Use the available methods.
// Listen to login events
w.OnLogin(func(i astilectron.Event) (username, password string, err error) {
// Process the request and auth info
if i.Request.Method == "GET" && i.AuthInfo.Scheme == "http://" {
username = "username"
password = "password"
}
return
})
Features and roadmap
Cheers to
go-thrust which is awesome but unfortunately not maintained anymore. It inspired this project.
Author: Asticode
Source Code: https://github.com/asticode/go-astilectron
License: MIT license