Compare commits

..

726 Commits

Author SHA1 Message Date
Gregory Schier
8cf45ba97f Bump version 2024-05-12 12:11:14 -07:00
Gregory Schier
6749fa9348 Add curl banner to import dialog 2024-05-10 13:36:30 -07:00
Gregory Schier
0f739834c8 Change curl import to post-toast 2024-05-10 13:06:40 -07:00
Gregory Schier
2d69b83765 Toast component and use for copy-as-curl 2024-05-10 12:37:04 -07:00
Gregory Schier
fa1765f356 Insomnia YAML and loading state on import 2024-05-10 09:46:20 -07:00
Gregory Schier
d1a0265ea5 Some fixes after upgrading react-query 2024-05-10 09:19:29 -07:00
Gregory Schier
bc191fec95 Update deps 2024-05-10 08:52:06 -07:00
Gregory Schier
43d042ae68 Fix paste handler in Editor.tsx 2024-05-09 23:17:43 -07:00
Gregory Schier
bb47fda7e1 Fix release targets 2024-05-09 15:38:27 -07:00
Gregory Schier
f98f541a3d Don't commit .cargo 2024-05-09 10:17:35 -07:00
Gregory Schier
4ea943d7f1 Fix args 2024-05-09 09:35:39 -07:00
Gregory Schier
a6fac2460b Update GH action 2024-05-09 09:33:47 -07:00
Gregory Schier
50410d262f Try fix linux 2024-05-09 08:37:18 -07:00
Gregory Schier
388d227572 Fix env var in GH Action 2024-05-09 08:29:45 -07:00
Gregory Schier
d07e80cc19 Fix curl export tests 2024-05-09 08:18:06 -07:00
Gregory Schier
8d987cff31 Default .app/.dev/etc domains to https protos 2024-05-09 08:16:06 -07:00
Gregory Schier
c46e976932 Bump version for beta 2024-05-09 07:52:36 -07:00
Gregory Schier
e33f273d7b Fix GRPC event.emit permissions 2024-05-09 07:45:00 -07:00
Gregory Schier
f16ced534c Import from Curl 2024-05-09 07:31:52 -07:00
Gregory Schier
f05abf97a4 Package lock 2024-05-08 15:37:53 -07:00
Gregory Schier
71b06c5261 Slight refactor to copy-as-curl 2024-05-08 00:28:40 -07:00
Gregory Schier
6639b07568 Add rename request to context menu
Closes #21
2024-05-08 00:08:18 -07:00
Gregory Schier
b196e51f1f Copy as curl 2024-05-08 00:00:50 -07:00
Gregory Schier
edc4fe3d9a Curl import (#24) 2024-05-07 21:57:03 -07:00
Gregory Schier
74065a320c Upgrade to Tauri 2.0 (#23) 2024-05-04 14:14:19 -07:00
Gregory Schier
87946c6c9f Fix horizontal scroll on GraphQL variables editor 2024-04-18 10:53:36 -07:00
Gregory Schier
4a58f73aa4 Oops 2024-04-02 10:11:37 +02:00
Gregory Schier
bd17650799 Postman text body import 2024-04-02 10:10:16 +02:00
Gregory Schier
db6a7dcabb Bump version 2024-04-01 08:48:26 +02:00
Gregory Schier
00b1f90074 Separate floating sidebar hidden state 2024-03-22 10:43:10 -07:00
Gregory Schier
e292235792 Filtering for cmd palette 2024-03-22 10:42:45 -07:00
Gregory Schier
5f86802d88 Space between var placeholders and code fold cursor 2024-03-22 10:42:35 -07:00
Gregory Schier
acb7f2e49b Fix Postman variable import 2024-03-22 10:40:51 -07:00
Gregory Schier
e2a15609bf Adjust highlight color 2024-03-22 10:37:45 -07:00
Gregory Schier
aa3bfd78c4 Some scrolling tweaks 2024-03-20 17:27:47 -07:00
Gregory Schier
23c4971127 Fix URL bar buttons in expanded state 2024-03-20 16:17:05 -07:00
Gregory Schier
40669217fb Bump version 2024-03-20 16:05:14 -07:00
Gregory Schier
8089ea87e8 Fix dialog height 2024-03-20 16:05:01 -07:00
Gregory Schier
9de24e3a40 Remove openOnHotKeyAction in favor of putting hotkey on the trigger button= 2024-03-20 15:56:39 -07:00
Gregory Schier
5afb8e7383 Use SQLite connect options 2024-03-20 13:33:11 -07:00
Gregory Schier
b3e3f22211 Pass workspace id to import 2024-03-20 07:30:59 -07:00
Gregory Schier
1ff6ff16b3 Handle import errors 2024-03-20 07:27:12 -07:00
Gregory Schier
b8a692f1a5 Postman bearer, global auth, global vars 2024-03-20 07:26:46 -07:00
Gregory Schier
5506cdd05f Implement select for command palette 2024-03-19 17:24:57 -07:00
Gregory Schier
4180fecb4b Tweak checkbox and autocomplete styles 2024-03-19 17:08:06 -07:00
Gregory Schier
fa257fdb18 Fix sidebar border 2024-03-19 16:44:37 -07:00
Gregory Schier
2da141ea16 Export multiple workspaces 2024-03-19 13:43:33 -07:00
Gregory Schier
1993361f87 Fix settings query store and analytics 2024-03-19 10:23:21 -07:00
Gregory Schier
a5dd3beb73 Start of command palette 2024-03-18 17:09:01 -07:00
Gregory Schier
17423f8c54 useRequests hook 2024-03-18 13:49:36 -07:00
Gregory Schier
8f495b9ade Fix editor key events 2024-03-18 13:40:15 -07:00
Gregory Schier
46b9b758fe Simple tests for Postman and Yaak importers 2024-03-18 13:40:00 -07:00
Gregory Schier
b0e84aac0c Set filename on Multipart part 2024-03-18 13:24:27 -07:00
Gregory Schier
20de2aeacc Fix GraphQL editor large variables quirk 2024-03-18 13:10:55 -07:00
Gregory Schier
7198534640 Fix postman import and import Insomnia gRPC 2024-03-18 08:18:04 -07:00
Gregory Schier
7e8ec36474 Better padding 2024-03-16 13:59:06 -07:00
Gregory Schier
52d1602d35 Remove debug log 2024-03-16 12:50:27 -07:00
Gregory Schier
e5731ceb1f Custom content-type for multipart items 2024-03-16 12:49:17 -07:00
Gregory Schier
3ed5a47a83 Content menu on entire sidebar 2024-03-16 10:47:10 -07:00
Gregory Schier
262a29ca5d Obfuscate environment variables 2024-03-16 10:42:46 -07:00
Gregory Schier
4a3e599128 Fix light mode text selection 2024-03-16 09:48:55 -07:00
Gregory Schier
7ebe844643 Stubbed out global commands helper 2024-03-16 09:46:11 -07:00
Gregory Schier
a49b72eebc Fix deleting workspace staying on deleted workspace path 2024-03-15 13:07:02 -07:00
Gregory Schier
bba3afa0b7 Bump version 2024-03-10 18:15:00 -07:00
Gregory Schier
221e768b33 Fix recent workspaces 2024-03-10 17:42:25 -07:00
Gregory Schier
c2dc7e0f4a Fix adding header if not exist 2024-03-10 17:10:16 -07:00
Gregory Schier
9e065c34ee Remove completion debug blur thing 2024-03-10 16:46:18 -07:00
Gregory Schier
2f91d541c5 Adjust detected content-type header 2024-03-10 16:26:06 -07:00
Gregory Schier
948fd487ab Clickable links in response viewer 2024-03-10 13:41:44 -07:00
Gregory Schier
ed6a5386a2 Better error handling for file not found 2024-03-10 11:02:32 -07:00
Gregory Schier
8a24c48fd3 Cancel file selection sets to undefined 2024-03-10 10:57:49 -07:00
Gregory Schier
d726a6f5bf Binary file uploads and missing workspace empty state 2024-03-10 10:56:38 -07:00
Gregory Schier
8d2a2a8532 Fix GraphQL Header backend 2024-02-28 13:38:22 -08:00
Gregory Schier
b838a6ffc1 Fix GraphQL content type on creation, and placeholder 2024-02-28 13:04:17 -08:00
Gregory Schier
2174a91b64 Include default protoc includes 2024-02-28 09:45:11 -08:00
Gregory Schier
083f83ccab Bump version 2024-02-28 08:51:34 -08:00
Gregory Schier
4f749be2e2 Fix dropdown arrow keys 2024-02-28 08:51:08 -08:00
Gregory Schier
cefdc3ecf3 Track GRPC 2024-02-28 07:32:05 -08:00
Gregory Schier
02960d2d64 Analytics ID 2024-02-28 07:27:19 -08:00
Gregory Schier
9e5226aa83 Analytics ID 2024-02-28 07:26:02 -08:00
Gregory Schier
63d7a44586 Remove Escape from hotkeys 2024-02-27 18:58:41 -08:00
Gregory Schier
c851dfe206 Fix sidebar focus 2024-02-27 10:33:20 -08:00
Gregory Schier
6adc15a249 Fix gap in dropdown menu items 2024-02-27 10:27:04 -08:00
Gregory Schier
9ac7aac296 Methods in recent dropdown 2024-02-27 10:20:35 -08:00
Gregory Schier
325d63e1b7 Many hotkey improvements 2024-02-27 10:10:38 -08:00
Gregory Schier
e639a77165 Info logs in build 2024-02-26 17:27:08 -08:00
Gregory Schier
c075efc752 Introspection tweak 2024-02-26 17:24:44 -08:00
Gregory Schier
c4f42f71c3 Tweak editor find/replace 2024-02-26 17:17:37 -08:00
Gregory Schier
535adfe200 Fix find/replace CM styling 2024-02-26 17:07:09 -08:00
Gregory Schier
85fa159f0d Fix lint errors 2024-02-26 07:43:08 -08:00
Gregory Schier
fd2fe46c95 Autocomplete icons and transfer proto files on duplicate 2024-02-26 07:39:53 -08:00
Gregory Schier
6e52f35626 Prompt folder name on create 2024-02-26 07:14:27 -08:00
Gregory Schier
a0d1e7023d Better creation from folder menu 2024-02-26 07:09:59 -08:00
Gregory Schier
97a2f00d59 Auto-fill link to changelog in release script 2024-02-25 18:42:04 -08:00
Gregory Schier
50ad4efad7 Protoc sidecar 2024-02-25 17:43:29 -08:00
Gregory Schier
79a3d9c8df Fix deletion in sidebar 2024-02-25 12:56:57 -08:00
Gregory Schier
b8e20d885f Fix create dropdown hotkey 2024-02-24 22:02:04 -08:00
Gregory Schier
752eb3dbd5 Try changing macOS version 2024-02-24 21:25:58 -08:00
Gregory Schier
616acdfb56 Bump some things 2024-02-24 21:23:02 -08:00
Gregory Schier
b2bcbababe Fix response pane height 2024-02-24 19:31:59 -08:00
Gregory Schier
9f5a3ef96a Don't build plugins 2024-02-24 18:58:51 -08:00
Gregory Schier
d2c5bdc3c8 Remove npm ci plugins 2024-02-24 18:28:07 -08:00
Gregory Schier
0d6899a12c Check in built plugins again 2024-02-24 18:27:36 -08:00
Gregory Schier
1b25cb0c4c Add pkg locks 2024-02-24 18:19:16 -08:00
Gregory Schier
783b7222df Install plugins in CI 2024-02-24 16:29:22 -08:00
Gregory Schier
ff3165ab30 Bump version 2024-02-24 16:22:55 -08:00
Gregory Schier
9780dc88a1 Got json-schema autocomplete working again 2024-02-24 16:22:22 -08:00
Gregory Schier
e4f0d2a341 Proto files off model 2024-02-24 14:16:58 -08:00
Gregory Schier
bcf0ae159d Better gRPC status on error 2024-02-24 12:41:43 -08:00
Gregory Schier
5664d41073 More analytics, and cancel requests 2024-02-24 11:30:07 -08:00
Gregory Schier
e75e6865ea Hook up empty state buttons for first-launch experience 2024-02-23 16:34:19 -08:00
Gregory Schier
fd5b495b70 gRPC in import/export 2024-02-23 16:16:13 -08:00
Gregory Schier
16506d1ddd Everything in messages now 2024-02-22 19:51:30 -08:00
Gregory Schier
e3016f7100 Format XML responses 2024-02-22 01:00:02 -08:00
Gregory Schier
766da4327c Refactor into grpc events 2024-02-22 00:49:22 -08:00
Gregory Schier
6f389b0010 Fix split layout placeholder 2024-02-18 09:12:44 -08:00
Gregory Schier
007ea88edd Add other body type 2024-02-18 08:59:14 -08:00
Gregory Schier
5409678855 Add metadata and squash migrations 2024-02-18 08:35:31 -08:00
Gregory Schier
4c6bd63b8b Better environment edit dialog 2024-02-18 07:44:53 -08:00
Gregory Schier
8db80d2e97 Allow editing base environment 2024-02-18 00:14:47 -08:00
Gregory Schier
c80fca8063 Render gRPC message body 2024-02-18 00:14:26 -08:00
Gregory Schier
7384398813 gRPC authentication 2024-02-17 23:47:28 -08:00
Gregory Schier
b57ea8adeb Even better dropdown filtering 2024-02-17 22:27:01 -08:00
Gregory Schier
8ff2caf3c3 Started gRPC tabs 2024-02-17 22:15:44 -08:00
Gregory Schier
a521b8f308 Better dropdown filtering 2024-02-17 22:03:42 -08:00
Gregory Schier
50ba167516 Prevent dragging folders into itself 2024-02-17 15:32:15 -08:00
Gregory Schier
cb102657ea Fix deps 2024-02-17 15:20:13 -08:00
Gregory Schier
a7d9e2432b Upgrade Vite deps and fix windows DnD 2024-02-17 14:57:12 -08:00
Gregory Schier
d842b168e6 Fix postman importer TS ref 2024-02-17 11:05:57 -08:00
Gregory Schier
870cb25980 Add more info to settings 2024-02-17 11:04:19 -08:00
Gregory Schier
fde0c5540b Adjust placeholder error colors 2024-02-15 21:15:18 -08:00
Gregory Schier
2ec9a1c19d Tweak tab padding 2024-02-15 16:38:14 -08:00
Gregory Schier
c2f5a3bf45 Responsive (scroll) workspace header 2024-02-15 16:30:08 -08:00
Gregory Schier
7c18eeae8c Better button highlight border 2024-02-15 15:55:32 -08:00
Gregory Schier
d7a1b4b7bc Refactor recentRequest/Env/Workspace 2024-02-15 15:14:18 -08:00
Gregory Schier
4566ede184 Better sidebar collapse, debuonce container uqeries, fix recent requests 2024-02-15 15:07:15 -08:00
Gregory Schier
f45c898be0 Better recent work/env/req logic 2024-02-13 17:21:54 -08:00
Gregory Schier
4e1700f8a4 Fix active environment on workspace change 2024-02-13 16:42:07 -08:00
Gregory Schier
f14311d14a Active environment in query param 2024-02-13 16:32:31 -08:00
Gregory Schier
470a7e2278 Better variable placeholder styles 2024-02-13 16:32:17 -08:00
Gregory Schier
2d67be481d Show GQL for graphql requests in sidebar 2024-02-13 16:32:00 -08:00
Gregory Schier
9f6ddb1558 Better highlight on JSON tree 2024-02-13 16:31:38 -08:00
Gregory Schier
853f07b9af Cmd+n to open dropdown 2024-02-11 14:17:09 -08:00
Gregory Schier
0eb6358387 Tab-to-indent in editor 2024-02-11 14:16:36 -08:00
Gregory Schier
d43e045f25 Make editor variables more prominent 2024-02-11 14:16:25 -08:00
Gregory Schier
17432fca29 Fix dropdown open index 2024-02-11 14:16:11 -08:00
Gregory Schier
d5931660c2 Catch URL error when URL = "{{HOST}}" 2024-02-11 09:04:27 -08:00
Gregory Schier
cd7678b7a1 Grap gRPC status codes 2024-02-11 08:52:12 -08:00
Gregory Schier
706be1188b Use basemsg 2024-02-11 08:29:57 -08:00
Gregory Schier
8989b61a13 Combine grpc handlers, fix duplicate 2024-02-10 10:41:45 -08:00
Gregory Schier
a997944f16 Fix response emit and sidebar flex 2024-02-09 16:16:02 -08:00
Gregory Schier
f8e8f5d3f2 Sidebar methods and fix model hooks 2024-02-09 16:09:24 -08:00
Gregory Schier
812e5238ac Fix editor selection/cursor and lint errors 2024-02-09 14:32:58 -08:00
Gregory Schier
16d4f2952d Remove built plugins from source control 2024-02-09 05:09:37 -08:00
Gregory Schier
ac9a6d5871 Merge branch 'grpc' 2024-02-09 05:07:45 -08:00
Gregory Schier
4fcf1df61f Move plugins to build folder 2024-02-09 05:07:34 -08:00
Gregory Schier
394beb374e gRPC Support (#20) 2024-02-09 05:01:00 -08:00
Gregory Schier
ba4d1063e3 Better message serialization 2024-02-09 05:00:48 -08:00
Gregory Schier
2bd9b436e6 Working sidebar actions for grpc 2024-02-07 00:02:02 -08:00
Gregory Schier
915a59dec4 Change hotkey handling to capture phase 2024-02-06 23:44:10 -08:00
Gregory Schier
ae2b746cb2 Fix pool management 2024-02-06 23:26:24 -08:00
Gregory Schier
b04cff153b Minor tweaks 2024-02-06 19:32:03 -08:00
Gregory Schier
bd8e71e567 gRPC schema from files! 2024-02-06 19:20:32 -08:00
Gregory Schier
562a36d616 Proto selection UI/models 2024-02-06 12:29:23 -08:00
Gregory Schier
c85a11edf1 Better reflect failure UI 2024-02-05 14:50:47 -08:00
Gregory Schier
ef7f942a8f Async connection management 2024-02-05 11:29:27 -08:00
Gregory Schier
a7f2a86d71 Refactor model emit, and recent conn dropdown 2024-02-05 10:39:47 -08:00
Gregory Schier
bf90f84d16 db to app_handle! 2024-02-04 22:52:04 -08:00
Gregory Schier
4284aa2549 Single upserted_model event 2024-02-04 21:19:15 -08:00
Gregory Schier
60773cab53 Fix DB mutex deadlock 2024-02-04 21:17:05 -08:00
Gregory Schier
e2c17873ae More messages 2024-02-04 19:08:31 -08:00
Gregory Schier
88982156ee Client streaming working 2024-02-04 17:53:15 -08:00
Gregory Schier
722c8a1c6b Bidirectional working 2024-02-04 14:10:38 -08:00
Gregory Schier
8c15274786 Messages are flowing! 2024-02-04 12:09:10 -08:00
Gregory Schier
1abba4980a Use req/conn/msg models in unary/server 2024-02-04 11:57:12 -08:00
Gregory Schier
3a340999ec Remove console log 2024-02-03 13:39:45 -08:00
Gregory Schier
b7261e77aa Grpc layout use new models 2024-02-03 13:28:31 -08:00
Gregory Schier
23431b40e9 Show gRPC requests in sidebar 2024-02-03 13:08:24 -08:00
Gregory Schier
04f31cd4a7 gRPC models and tables 2024-02-03 11:14:42 -08:00
Gregory Schier
7d82a7e74a Tiny fixes 2024-02-02 18:41:00 -08:00
Gregory Schier
d31255d987 Better formatting 2024-02-02 13:37:44 -08:00
Gregory Schier
e53693f605 A bit better handling of responses 2024-02-02 13:32:06 -08:00
Gregory Schier
67aa7b7268 Split layouts and things 2024-02-02 12:41:37 -08:00
Gregory Schier
e27ed9becc bidi hacked! 2024-02-02 01:10:54 -08:00
Gregory Schier
22d21af3c2 Implement cancel 2024-02-02 00:18:37 -08:00
Gregory Schier
67000af7f9 Better connection management 2024-02-01 20:29:32 -08:00
Gregory Schier
b84c7ba50c gRPC manager mostly working 2024-02-01 15:36:50 -08:00
Gregory Schier
a0b3f86462 Small refactor 2024-02-01 02:42:59 -08:00
Gregory Schier
6a8395660d Refactor commands and DB 2024-02-01 02:29:24 -08:00
Gregory Schier
2c041fbac6 Some minor tweaks 2024-02-01 00:48:03 -08:00
Gregory Schier
1eed0e8f22 Revert response JSON tree 2024-02-01 00:38:57 -08:00
Gregory Schier
63a0ed273d Even better styles 2024-02-01 00:36:49 -08:00
Gregory Schier
d0be5ca515 Styled it up a bit 2024-02-01 00:16:09 -08:00
Gregory Schier
b964c942d6 Merge remote-tracking branch 'origin/grpc' into grpc 2024-01-31 22:14:15 -08:00
Gregory Schier
a05fc5fd20 Hacky server streaming done 2024-01-31 22:14:08 -08:00
Gregory Schier
de183abd24 Hacky client streaming done 2024-01-31 22:13:46 -08:00
Gregory Schier
5c44df7b00 Initial frontend for gRPC UI 2024-01-30 16:43:54 -08:00
Gregory Schier
dbdce4cf9a Hooked up test call from frontend! 2024-01-29 20:50:43 -08:00
Gregory Schier
219a6b78da Fix cookie jar 2024-01-28 17:49:04 -08:00
Gregory Schier
fb11aff03f Track dialogs 2024-01-28 16:33:36 -08:00
Gregory Schier
15714ae188 Fix dropdown separator 2024-01-28 16:21:41 -08:00
Gregory Schier
ce116d032d Better format 2024-01-28 16:19:46 -08:00
Gregory Schier
6f41df6e52 More response info 2024-01-28 16:02:49 -08:00
Gregory Schier
0853d2ca95 Better BG color 2024-01-28 14:43:04 -08:00
Gregory Schier
6798331ce5 Cookie Support (#19) 2024-01-28 14:39:51 -08:00
Gregory Schier
5ffc75e0ad Add shift to hotkey dialog hotkey 2024-01-19 22:11:20 -08:00
Gregory Schier
bf92371a49 Show alert after force checking updates 2024-01-19 22:11:02 -08:00
Gregory Schier
bd3da86317 Better dialog padding 2024-01-19 22:08:32 -08:00
Gregory Schier
3db3d42246 Change env hotkey to use shift 2024-01-19 21:53:48 -08:00
Gregory Schier
de8bf3ca70 Fix URL 2px grow on focus 2024-01-19 21:49:51 -08:00
Gregory Schier
8bc131de6c Bump version 2024-01-19 13:42:02 -08:00
Gregory Schier
efce69292d Fix analytics again 2024-01-18 22:28:25 -08:00
Gregory Schier
0ccc893440 Fix dialog close button 2024-01-18 20:57:42 -08:00
Gregory Schier
1f9756c917 Fix URLBar expanded state inner buttons 2024-01-18 20:40:56 -08:00
Gregory Schier
be8f0e4521 Some analytics fixes 2024-01-18 20:23:02 -08:00
Gregory Schier
bcdf51d231 Launch analytics events, changelog, better filter styles 2024-01-18 14:42:02 -08:00
Gregory Schier
1a1553eebd Bump version 2024-01-17 14:56:47 -08:00
Gregory Schier
321c3862fe Custom HTTP method names 2024-01-17 14:52:19 -08:00
Gregory Schier
466d412e65 Workspace header tweak Windows 2024-01-17 18:48:43 -08:00
Gregory Schier
86f50b826f Fix header in fullscreen mode on Mac 2024-01-17 09:34:47 -08:00
Gregory Schier
ac1e646e68 Download response, and some fixes 2024-01-16 17:02:55 -08:00
Gregory Schier
33374eefc7 Fix editor toolbar blocking things 2024-01-15 21:44:53 -08:00
Gregory Schier
7047df4f7e Better request creation (Closes #14) 2024-01-15 21:39:27 -08:00
Gregory Schier
c8bd4d0ae0 XPath plugin 2024-01-15 21:27:47 -08:00
Gregory Schier
1e79f76701 Fix send icon 2024-01-15 15:43:55 -08:00
Gregory Schier
18852dca06 Switch to Lucide icons 2024-01-15 15:42:28 -08:00
Gregory Schier
408e7e80b7 Improve response filter UX 2024-01-15 15:19:29 -08:00
Gregory Schier
fc185de023 JSONPath filter plugins working 2024-01-15 15:06:49 -08:00
Gregory Schier
bb9d3a42f3 Move plugin stuff around 2024-01-15 14:33:51 -08:00
Gregory Schier
baf0f4291d Fix request duplication 2024-01-15 13:47:44 -08:00
Gregory Schier
536066142c Fix workspace defaults 2024-01-15 12:25:13 -08:00
Gregory Schier
04cf16497d Better settings dialog 2024-01-15 12:16:44 -08:00
Gregory Schier
feb5972090 Fix resize observer 2024-01-15 12:02:08 -08:00
Gregory Schier
77bf5a58d8 Move request-related settings to workspace 2024-01-15 11:52:36 -08:00
Gregory Schier
3539642491 Bump beta version 2024-01-14 20:30:25 -08:00
Gregory Schier
08abea6a6f fix mac decorations 2024-01-14 17:22:31 -08:00
Gregory Schier
0045b85f00 Integrated titlebar windows 2024-01-14 16:44:04 -08:00
Gregory Schier
4b34c3d101 Further titlebar tweaks 2024-01-14 12:02:44 -08:00
Gregory Schier
4af0a15d9f Better titlebar control icons 2024-01-14 11:56:21 -08:00
Gregory Schier
3a4a76c58d Basic Linux/Windows integrated titlebar 2024-01-13 23:40:32 -08:00
Gregory Schier
3086d815c1 Fix hotkey formatting 2024-01-12 22:12:01 -08:00
Gregory Schier
a48a9eab4a beta tag 2024-01-12 22:00:55 -08:00
Gregory Schier
48664c66e5 fix appearance init 2024-01-12 21:59:46 -08:00
Gregory Schier
7aee5176a9 Vendor Openssl 2024-01-12 21:03:28 -08:00
Gregory Schier
0da68ced18 Hotkeys for request switcher 2024-01-12 21:03:20 -08:00
Gregory Schier
39f7d9c113 Appearance setting and gzip/etc support 2024-01-12 13:39:08 -08:00
Gregory Schier
138943bfb6 Initial settings implementation 2024-01-11 21:13:17 -08:00
Gregory Schier
c1c9f882a6 Dropdown manages hotkeys now 2024-01-11 10:18:05 -08:00
Gregory Schier
1bcf26f656 Hotkey for keyboard shortcut help 2024-01-10 22:05:16 -08:00
Gregory Schier
7c2466da5e Bump version number 2024-01-10 16:25:55 -08:00
Gregory Schier
7dc78a1f6f Add hotkey dialog and rust-only analytics 2024-01-10 16:18:08 -08:00
Gregory Schier
88d024023b Fix beta icon 2024-01-08 17:07:42 -08:00
Gregory Schier
626aacf982 Bump version to 2024.0.0 2024-01-08 15:57:59 -08:00
Gregory Schier
d5855c45a6 Hotkey labels 2024-01-08 15:57:21 -08:00
Gregory Schier
793bff9f27 Show hotkeys on empty views 2024-01-08 15:13:44 -08:00
Gregory Schier
88ea68e72f Remove base env, fix hotkeys, and QoL improvements 2024-01-07 22:24:19 -08:00
Gregory Schier
35e40d2c55 Fix hotkeys getting stuck on cmd+tab 2024-01-07 21:32:25 -08:00
Gregory Schier
c472b83409 Always show settings dropdown 2023-11-22 09:39:30 -08:00
Gregory Schier
52c26d235c Tweak margin 2023-11-22 09:37:50 -08:00
Gregory Schier
ac54729012 Fix bottom-up dropdown positioning 2023-11-22 09:35:56 -08:00
Gregory Schier
0586034ef4 Bump version 2023-11-22 09:06:47 -08:00
Gregory Schier
91790ba708 Better linux/Windows support for hotkeys 2023-11-22 09:06:22 -08:00
Gregory Schier
d8ab6c0b50 Good hotkey support 2023-11-22 09:01:48 -08:00
Gregory Schier
b600a21a2b Reset URL bar when request changes 2023-11-21 23:26:29 -08:00
Gregory Schier
4f9d1278f7 Env dialog hotkey 2023-11-21 22:35:28 -08:00
Gregory Schier
15aa93f5f9 Remove response body and basic hotkeys 2023-11-21 22:15:01 -08:00
Gregory Schier
c7798092d8 Remove app-specific menu items 2023-11-21 19:18:40 -08:00
Gregory Schier
5560593aaa Fix macOS menu and fallback URL 2023-11-21 09:24:13 -08:00
Gregory Schier
66639e651d Hide menu on windows/linux 2023-11-21 08:17:37 -08:00
Gregory Schier
8e42d5ccdb Disable sandboxing (again) 2023-11-19 21:59:55 -08:00
Gregory Schier
5c62594087 Fix drag-drop reorder 2023-11-19 21:43:01 -08:00
Gregory Schier
26b6c48657 Postman ID generation 2023-11-19 20:54:02 -08:00
Gregory Schier
0290aba982 Bump beta.3 2023-11-19 20:46:55 -08:00
Gregory Schier
0bafc4e4f5 Postman variables + urlencoded forms 2023-11-19 20:29:24 -08:00
Gregory Schier
9a36f94279 Add back Windows/Linux builds 2023-11-19 18:22:13 -08:00
Gregory Schier
1d8e66179e Remove Tauri context menu plugin 2023-11-19 18:21:10 -08:00
Gregory Schier
fda6d16d8e Fix header padding windows/linux 2023-11-19 18:14:49 -08:00
Gregory Schier
c4737916df Some tweaks 2023-11-19 18:13:32 -08:00
Gregory Schier
919465cdbb Beta 2 2023-11-19 17:41:58 -08:00
Gregory Schier
de3730fa4f Network entitlement 2023-11-19 17:41:46 -08:00
Gregory Schier
aff26fdd46 Try sandboxing again 2023-11-19 17:06:31 -08:00
Gregory Schier
3c0edf06af Remove sandboxing 2023-11-17 09:33:16 -08:00
Gregory Schier
cb8939db88 touch 2023-11-17 08:00:04 -08:00
Gregory Schier
bf4b3213c4 Out of beta 2023-11-17 07:53:26 -08:00
Gregory Schier
633d7c52c4 Tweak 2023-11-17 07:52:03 -08:00
Gregory Schier
0401cb92aa Format GraphQL variables 2023-11-17 07:51:03 -08:00
Gregory Schier
bff6c668a0 Drag into folder (Closes #8) 2023-11-17 07:36:01 -08:00
Gregory Schier
ee87e65763 Mostly move some stuff around 2023-11-16 18:53:34 -08:00
Gregory Schier
f165a0b827 Better update logic 2023-11-14 14:28:06 -08:00
Gregory Schier
f7426dc8ce Better dropdown menu 2023-11-14 10:56:56 -08:00
Gregory Schier
6114039f7e Version to beta 2023-11-14 10:07:39 -08:00
Gregory Schier
da414debe1 Beta channel updates 2023-11-14 08:57:46 -08:00
Gregory Schier
11f5541558 Multipart form UI and fixes 2023-11-14 00:32:02 -08:00
Gregory Schier
1bc155d684 Got multipart working (text-only) 2023-11-13 23:26:11 -08:00
Gregory Schier
335231060e Fix window title moving stoplights (for now) 2023-11-13 23:25:47 -08:00
Gregory Schier
0fdf64440f Postman import form data 2023-11-13 11:48:28 -08:00
Gregory Schier
a984fb33dc Some small improvements 2023-11-13 11:44:29 -08:00
Gregory Schier
41b1ec96c9 Form urlencoded bodies! 2023-11-13 11:28:37 -08:00
Gregory Schier
df83a61d6f Url parameters done 2023-11-13 10:52:11 -08:00
Gregory Schier
d289f1fd13 Minor tweaks 2023-11-12 21:16:42 -08:00
Gregory Schier
aea4e961aa Custom updater code 2023-11-12 21:16:33 -08:00
Gregory Schier
c554b73d48 Request body is now an object 2023-11-12 11:16:12 -08:00
Gregory Schier
b519bff3d6 Some postman import improvements 2023-11-11 10:43:11 -08:00
Gregory Schier
8381104302 Sync window title (Closes #13) 2023-11-10 15:55:50 -08:00
Gregory Schier
5ef7c6a1a2 Dev app icon 2023-11-10 13:06:12 -08:00
Gregory Schier
6d7a81850c Upgrade sqlx 2023-11-10 12:28:33 -08:00
Gregory Schier
6e5d5fcb95 Clean up importers 2023-11-10 11:39:17 -08:00
Gregory Schier
004fef6729 Fix is_empty check 2023-11-10 09:12:20 -08:00
Gregory Schier
0bec5a6405 Postman importer semi-complete 2023-11-10 09:08:20 -08:00
Gregory Schier
60b091ff1c Tidy up logs and general cleanup 2023-11-09 20:33:09 -08:00
Gregory Schier
bee1a5cb2d Move error alert to hook 2023-11-09 20:02:42 -08:00
Gregory Schier
bb2d3dd5b1 Show import errors 2023-11-09 20:00:19 -08:00
Gregory Schier
bf8aad04c7 Hacky Yaak import complete! 2023-11-09 19:40:31 -08:00
Gregory Schier
4306294a72 More fallback request handing 2023-11-09 17:42:10 -08:00
Gregory Schier
10f3722fe3 Request fallback name in header 2023-11-09 17:34:57 -08:00
Gregory Schier
c1af9ca44a Better default request names 2023-11-09 17:26:04 -08:00
Gregory Schier
5b230c74f0 Better non-named requests 2023-11-09 17:17:03 -08:00
Gregory Schier
5cebb4e61a Better Yaak export 2023-11-09 17:03:29 -08:00
Gregory Schier
bd9d1e2244 Refactor previous commit 2023-11-09 16:50:57 -08:00
Gregory Schier
9bdaa05f00 Default request name to URL(ish) 2023-11-09 16:47:00 -08:00
Gregory Schier
750ad0c902 Rename initial workspace to "Yaak" 2023-11-09 13:17:21 -08:00
Gregory Schier
a9c16838e6 No analytics in dev 2023-11-09 11:46:52 -08:00
Gregory Schier
d5065ab6d9 Analytics event properties 2023-11-09 11:44:59 -08:00
Gregory Schier
9ebb3ef532 Context menu, logs in DevTools, export, tweaks 2023-11-09 09:28:01 -08:00
Gregory Schier
aeda72f13e Fix plugin (again) 2023-11-08 13:33:15 -08:00
Gregory Schier
83aa9041cb Bundle plugin in Git 2023-11-08 13:06:49 -08:00
Gregory Schier
d51913509d Move plugins back 2023-11-08 12:34:14 -08:00
Gregory Schier
5106f28ba5 Fix permissions 2023-11-08 12:02:17 -08:00
Gregory Schier
0c55c6eaab Bump version 2023-11-08 10:12:01 -08:00
Gregory Schier
b0edbd19c8 Tweak theme 2023-11-08 10:11:29 -08:00
Gregory Schier
7630db79b7 Tweak theme 2023-11-08 09:56:13 -08:00
Gregory Schier
55a7b82567 Track screen size, os, and version 2023-11-08 09:49:29 -08:00
Gregory Schier
b5cb46918a Rust analytics and a few tweaks 2023-11-08 09:13:32 -08:00
Gregory Schier
a793ece1a5 Add basic analytics 2023-11-07 09:53:59 -08:00
Gregory Schier
0f6e4b641a Cancel responses on startup 2023-11-06 13:06:15 -08:00
Gregory Schier
5ac5fab0c6 Send all in a folder 2023-11-06 10:53:39 -08:00
Gregory Schier
8030a8a235 Rework workspace header 2023-11-06 10:42:59 -08:00
Gregory Schier
d98426cad3 Fix sidebar focus max recursion 2023-11-06 10:40:02 -08:00
Gregory Schier
06034a8fc4 Save after formatting GraphQL (Closes #9) 2023-11-06 07:20:47 -08:00
Gregory Schier
1ee9f9bb51 Move plugins back to root dir 2023-11-06 07:18:53 -08:00
Gregory Schier
4b99d1405e Persist sidebar collapsed state (Closes #10) 2023-11-06 07:18:42 -08:00
Gregory Schier
8480e52195 Vite to bundle insomnia plugin 2023-11-05 22:13:22 -08:00
Gregory Schier
243e65a992 Better import conversion 2023-11-05 14:46:08 -08:00
Gregory Schier
b82304a233 Basic import of request body and bearer auth 2023-11-05 14:35:25 -08:00
Gregory Schier
f7a4ea9735 Recursive Insomnia import! 2023-11-05 13:33:23 -08:00
Gregory Schier
33d1a84ecd Remove numbers from recent requests 2023-11-04 16:19:21 -07:00
Gregory Schier
f4a071ee05 Fix drop marker indent 2023-11-04 11:16:41 -07:00
Gregory Schier
e26ba0f9d0 Folder actions 2023-11-04 10:48:18 -07:00
Gregory Schier
b4e2a12375 Folder chevron icon 2023-11-03 23:10:44 -07:00
Gregory Schier
5e7aacd31a Fix arrow navigation for nested sidebar 2023-11-03 17:29:33 -07:00
Gregory Schier
00718df49e Folder-based drag-n-drop complete! 2023-11-03 16:29:21 -07:00
Gregory Schier
bb9025ab07 Sidebar ordering 95% done! 2023-11-03 15:02:17 -07:00
Gregory Schier
867f3908ed Nested sidebar ordering almost working 2023-11-03 14:08:46 -07:00
Gregory Schier
30e1ecac39 Add folder model 2023-11-03 07:49:44 -07:00
Gregory Schier
7eb2abe9b2 Even better focus state 2023-11-02 22:23:21 -07:00
Gregory Schier
a5ac8fa035 Remove focus on env sidebar buttons 2023-11-02 22:18:13 -07:00
Gregory Schier
dd705de155 Rearrange menus 2023-11-02 21:41:35 -07:00
Gregory Schier
b15cdec701 Refactor environment edit dialog 2023-11-02 20:38:33 -07:00
Gregory Schier
a99a36b5cc Base environments fully working 2023-11-02 18:43:39 -07:00
Gregory Schier
e0b0e3d781 Initial "plugin" system with importer (#7) 2023-11-02 18:08:43 -07:00
Gregory Schier
98a4834d4f Fix cursor color in single-line mode 2023-10-31 15:10:33 -07:00
Gregory Schier
32b135dbaf Fix sending of ephemeral requests 2023-10-30 08:24:49 -07:00
Gregory Schier
0fc8d12a06 Fix GQL introspection and bearer auth templating 2023-10-30 08:07:34 -07:00
Gregory Schier
3c2bdab101 Fix button styles 2023-10-30 07:27:27 -07:00
Gregory Schier
8b5d7ae3ed Fix editor stale callbacks and recent item deletion 2023-10-30 07:07:14 -07:00
Gregory Schier
51949f4fbf Refactored some core UI 2023-10-30 06:35:52 -07:00
Gregory Schier
6013cd2329 Plugin module loading 2023-10-29 20:50:23 -07:00
Gregory Schier
eba28ade48 Bump version 2023-10-29 17:22:27 -07:00
Gregory Schier
44af1ddc8a Fix sidebar scroll 2023-10-29 17:19:03 -07:00
Gregory Schier
63c0d09df8 A bit more playing with JS runtime 2023-10-29 17:05:48 -07:00
Gregory Schier
f305633d94 Initial "Hello World" for plugins 2023-10-29 16:43:28 -07:00
Gregory Schier
13155f8591 Fix request creation 2023-10-29 12:05:05 -07:00
Gregory Schier
f2ac97aa62 Restore recent environment on workspace change
Fixes #6
2023-10-29 11:32:55 -07:00
Gregory Schier
18eb0027a1 Fix var complete and env dialog actions 2023-10-29 11:18:55 -07:00
Gregory Schier
9e2803fcfb Remove broken key/value enter/backspace logic 2023-10-29 10:45:05 -07:00
Gregory Schier
705e30b6e0 Delete key/value on backspace 2023-10-29 10:26:38 -07:00
Gregory Schier
f1260911ea Move workspace menu, better env mgmt, QoL 2023-10-29 09:45:16 -07:00
Gregory Schier
076ff63dbe Bump version 2023-10-28 23:41:58 -07:00
Gregory Schier
899092b4d2 Better listening for path changes 2023-10-28 23:41:24 -07:00
Gregory Schier
c2c3a28aab Bump version 2023-10-28 22:14:51 -07:00
Gregory Schier
25c0db502e Fixed auto-focus in prompt and env dropdown 2023-10-28 22:14:12 -07:00
Gregory Schier
6dcbe45a53 Clear selected sidebar index on drag-drop end 2023-10-28 21:47:00 -07:00
Gregory Schier
e2b46f25ff Revert debug name 2023-10-28 21:43:09 -07:00
Gregory Schier
981182be46 Fix drag-n-drop things 2023-10-28 21:42:35 -07:00
Gregory Schier
ad164ebd5e Persist window paths 2023-10-28 21:23:46 -07:00
Gregory Schier
cacdad8826 Bump version to 2023.1.0 2023-10-28 19:15:33 -07:00
Gregory Schier
77e5142a7c Update placeholders when env changes 2023-10-28 19:14:51 -07:00
Gregory Schier
613081728d Placeholder error and fix env nav 2023-10-28 19:08:31 -07:00
Gregory Schier
23e77dfec1 Recent requests/workspaces. Closes #1 2023-10-28 18:46:54 -07:00
Gregory Schier
6e273ae2a3 Fix recent requests loading on startup 2023-10-28 18:27:18 -07:00
Gregory Schier
4061094988 Add tauri window save state plugin 2023-10-28 13:14:27 -07:00
Gregory Schier
82b185e27f Fix rustfmt 2023-10-28 12:45:25 -07:00
Gregory Schier
27dc261639 Handle enabled/disabled variables and render multi 2023-10-28 11:36:40 -07:00
Gregory Schier
7e45fecf19 Remove unused Variable type 2023-10-28 11:31:45 -07:00
Gregory Schier
1a5053380b Variables under Environment, and render all props 2023-10-28 11:29:29 -07:00
Gregory Schier
408665c62d Native Codemirror cursor 2023-10-27 13:14:41 -07:00
Gregory Schier
65efee2048 Only wrap URLBar on focus and hotkey to open recent requests 2023-10-27 12:40:43 -07:00
Gregory Schier
3faa66a1fc Resizing window no longer changes sidebar visibility
Fixes #4
2023-10-27 11:21:59 -07:00
Gregory Schier
9dafe4f704 Auto-expand URL bar height 2023-10-27 10:57:07 -07:00
Gregory Schier
356eaf1713 Environment deletion and better actions menu 2023-10-26 16:18:47 -07:00
Gregory Schier
f8584f1537 Stop autocomplete from jumping around 2023-10-26 15:27:48 -07:00
Gregory Schier
6ad6cb34b0 Fix request creation from menu 2023-10-26 10:41:14 -07:00
Gregory Schier
32b27cd780 Send requests with active environment 2023-10-26 10:32:06 -07:00
Gregory Schier
0344a1e8c9 Move create request and fix slow HTML highlighting 2023-10-26 09:42:19 -07:00
Gregory Schier
0515271c12 Better project selector, Fixes #2, and a bunch more 2023-10-26 09:11:44 -07:00
Gregory Schier
5ae8d54ce0 Fixed some routing and introspection requests 2023-10-25 21:53:18 -07:00
Gregory Schier
33c406ce49 Environments in URL and better rendering 2023-10-25 11:13:00 -07:00
Gregory Schier
3b660ddbd0 Move responses dropdown to separate component 2023-10-25 07:59:10 -07:00
Gregory Schier
3132728a27 Fix dialog height 2023-10-25 00:02:51 -07:00
Gregory Schier
7063128342 Better style when no active environment 2023-10-24 23:58:12 -07:00
Gregory Schier
2187775462 Environment dropdown and actions 2023-10-24 09:17:29 -07:00
Gregory Schier
18adcd1004 Started on environment edit dialog 2023-10-23 21:00:36 -07:00
Gregory Schier
b0656d1e38 Hacky implementation of variable autocomplete 2023-10-23 10:31:21 -07:00
Gregory Schier
38e66047e0 Rendered first variable! 2023-10-22 22:30:29 -07:00
Gregory Schier
c24f049dac Updating environments! 2023-10-22 22:06:51 -07:00
Gregory Schier
53d13c8172 Update .gitignore 2023-10-22 20:40:00 -07:00
Gregory Schier
0727c6e437 Prettier and start of env editor 2023-10-22 20:38:57 -07:00
Gregory Schier
8328d20150 Environments data model 2023-10-22 18:28:56 -07:00
Gregory Schier
afe6a3bf57 Environment data model backend 2023-10-22 16:05:09 -07:00
Gregory Schier
d920632cbd Fix some eslint warnings 2023-10-22 11:02:39 -07:00
Gregory Schier
5c456fd4d5 Add APPLE_TEAM_ID 2023-10-18 14:12:08 -07:00
Gregory Schier
38c247e350 Revert artifacts things 2023-10-18 13:25:35 -07:00
Gregory Schier
0c8f72124a Bump cargo deps 2023-10-18 13:25:20 -07:00
Gregory Schier
80ed6b1525 Bump version 2023-10-18 12:14:38 -07:00
Gregory Schier
4424b3f208 Fix sidebar drag-n-drop 2023-10-18 11:58:58 -07:00
Gregory Schier
2c75abce09 Retry button on introspection errors 2023-06-12 13:20:42 -07:00
Gregory Schier
4e15eb197f Fix autocomplete doc font size 2023-05-31 21:32:48 -07:00
Gregory Schier
a7544b4f8c Persist introspection queries and also improve 2023-05-31 21:29:41 -07:00
Gregory Schier
d126aad172 Update tauri NPM 2023-05-29 12:49:50 -07:00
Gregory Schier
acc5c0de50 Fix graphql instrospection 2023-05-29 12:31:34 -07:00
Gregory Schier
3391da111d Change version 2023-04-27 16:53:39 -07:00
Gregory Schier
e37ce96956 Version 1.0.0 2023-04-27 16:47:49 -07:00
Gregory Schier
c51831c975 Fix window methods on Linux/Windows 2023-04-27 16:27:02 -07:00
Gregory Schier
180aa39de4 Cross platform window controls 2023-04-27 10:19:49 -07:00
Gregory Schier
3bd780782e Fix ubuntu build 2023-04-26 17:00:30 -07:00
Gregory Schier
f9ba2f79c2 Windows and Linux 2023-04-26 16:54:51 -07:00
Gregory Schier
d9493de2be Bump version 2023-04-26 16:47:50 -07:00
Gregory Schier
bc9a623742 Very basic CSV viewer 2023-04-22 21:53:04 +08:00
Gregory Schier
532edbf274 Truncate response files 2023-04-14 14:15:33 -07:00
Gregory Schier
1585692328 Randomly offset new windows 2023-04-14 14:05:23 -07:00
Gregory Schier
083f565b12 Fix text encoding and delete responses 2023-04-14 13:50:41 -07:00
Gregory Schier
f7f7438c9e Delete response files 2023-04-14 12:17:11 -07:00
Gregory Schier
19934a93bb Readonly editor disable tabindex 2023-04-13 22:36:11 -07:00
Gregory Schier
577cfe5bdc Fix imageview padding 2023-04-13 22:33:47 -07:00
Gregory Schier
43ac6afae1 Duration and size tags 2023-04-13 20:50:17 -07:00
Gregory Schier
8cc11703d3 Comment 2023-04-13 18:55:32 -07:00
Gregory Schier
4f7a116378 Always store response on filesystem 2023-04-13 18:52:56 -07:00
Gregory Schier
513793d9ce Support binary responses! 2023-04-13 18:48:40 -07:00
Gregory Schier
67f32b6734 Blur backdrop 2023-04-11 16:12:26 -07:00
Gregory Schier
66813d67fe Autofocus buttons 2023-04-11 14:04:23 -07:00
Gregory Schier
a38691ed53 Better opening workspaces and redirect workspace to recent request 2023-04-11 11:11:36 -07:00
Gregory Schier
deeefdcfbf Button disabled style opacity 2023-04-10 16:03:45 -07:00
Gregory Schier
db292511b1 Dropdown keys and pointer events 2023-04-10 16:02:29 -07:00
Gregory Schier
1a5334c1ce Upgrade deno core 2023-04-10 11:16:25 -07:00
Gregory Schier
11002abe39 Tweak response history 2023-04-09 23:15:51 -07:00
Gregory Schier
d922dcb062 Fixed multi-window model sync 2023-04-09 22:32:47 -07:00
Gregory Schier
6fcaa18e86 Tweak recent requests 2023-04-09 22:25:00 -07:00
Gregory Schier
7664c941dd Toggle settings 2023-04-09 22:12:16 -07:00
Gregory Schier
6f5cb528c6 Fix sidebar request focus 2023-04-09 22:03:41 -07:00
Gregory Schier
ebb78922f0 More stuff on sidebar 2023-04-09 21:52:04 -07:00
Gregory Schier
2285fe9f1c Small tweaks 2023-04-09 15:32:13 -07:00
Gregory Schier
38ba8625d8 Request history navigator 2023-04-09 15:26:54 -07:00
Gregory Schier
ab5681c7ad Enter name on create workspace 2023-04-09 12:27:02 -07:00
Gregory Schier
f66dcb9267 Rename workspace 2023-04-09 12:23:41 -07:00
Gregory Schier
1b6cfbac77 Sidebar hover transitions 2023-04-06 16:30:46 -07:00
Gregory Schier
4c27e788ea Remove some more key value usage 2023-04-06 16:26:56 -07:00
Gregory Schier
769da0b052 A bunch of tweaks 2023-04-06 16:05:25 -07:00
Gregory Schier
6b60c86300 macOS 12 2023-04-06 08:39:30 -07:00
Gregory Schier
30c1b5e8c7 Remove system tray icon 2023-04-06 08:15:40 -07:00
Gregory Schier
10af9b6f99 Minor tweaks 2023-04-04 17:21:02 -07:00
Gregory Schier
aa8c066f2d Fix some things 2023-04-04 16:56:45 -07:00
Gregory Schier
b913b74449 Editor line wrapping support (not used yet) 2023-04-04 16:40:37 -07:00
Gregory Schier
b71adce50b remove janky last location tracking 2023-04-04 16:23:08 -07:00
Gregory Schier
0fbb44c701 Fix resize cursor 2023-04-04 16:12:45 -07:00
Gregory Schier
de335e8637 Better button styles 2023-04-04 15:40:25 -07:00
Gregory Schier
2999f63a4c Bump version 2023-04-04 13:56:24 -07:00
Gregory Schier
2abc5e6f0b Some small fixes 2023-04-04 13:56:14 -07:00
Gregory Schier
639de4321e A few fixes 2023-04-04 13:31:48 -07:00
Gregory Schier
b3c461afdd Better status tags and delete request on key 2023-04-04 12:36:30 -07:00
Gregory Schier
7d154800a0 Remove expects from request sending 2023-04-04 08:14:32 -07:00
Gregory Schier
b48ed0399e Fix web view height 2023-04-04 07:51:41 -07:00
Gregory Schier
c5d6e7d74a Fix autocomplete spacing 2023-04-04 07:51:19 -07:00
Gregory Schier
e82f915363 Fix input focus border 2023-04-03 12:19:37 -07:00
Gregory Schier
3128e9ce76 Hot keys and cleanup 2023-04-03 07:59:49 -07:00
Gregory Schier
bc0e86757c Add entitlemet for v8 2023-04-02 20:23:21 -07:00
Gregory Schier
fec99916c2 Debug codesigned build 2023-04-02 19:09:14 -07:00
Gregory Schier
3b5d059b11 Disable code signing 2023-04-02 18:27:14 -07:00
Gregory Schier
c3fe2acc8a Fix tauri script command 2023-04-02 17:25:24 -07:00
Gregory Schier
4d002c412b Fix universal binary 2023-04-02 17:12:20 -07:00
Gregory Schier
46d152b5f1 Bump version 2023-04-02 15:44:41 -07:00
Gregory Schier
25fa81ebbc Fix toolchain 2023-04-02 15:44:21 -07:00
Gregory Schier
7c2de3c360 Add proper target 2023-04-02 15:42:19 -07:00
Gregory Schier
3a3b187cd0 Try universal binary 2023-04-02 15:33:13 -07:00
Gregory Schier
3226bbe083 Fix version 2023-04-02 15:25:24 -07:00
Gregory Schier
a1e4e0e6c9 Bump version 2023-04-02 14:54:41 -07:00
Gregory Schier
b3aa8b893b Notorization (hopefully) 2023-04-02 14:53:49 -07:00
Gregory Schier
f057139634 Change tabs again 2023-04-02 11:11:53 -07:00
Gregory Schier
71a2b11ab4 Better response headers 2023-04-02 10:45:41 -07:00
Gregory Schier
587254a0e7 Show response headers 2023-04-01 23:43:22 -07:00
Gregory Schier
9f4de66f3c Some more refactoring 2023-04-01 21:48:30 -07:00
Gregory Schier
b0d8908724 Refactor debounce and tauri event listeners 2023-04-01 21:39:46 -07:00
Gregory Schier
15c22d98c6 Fix dropdown and dialog key handling 2023-04-01 21:04:39 -07:00
Gregory Schier
3105ae0edc Refactor sidebar display 2023-04-01 20:58:53 -07:00
Gregory Schier
11a89f06c1 Better GraphQL schema fetching 2023-04-01 17:53:36 -07:00
Gregory Schier
9cbe24e740 More eslint fixes 2023-04-01 15:48:37 -07:00
Gregory Schier
bfbed13b8f Add React hooks eslint 2023-04-01 15:26:57 -07:00
Gregory Schier
2268de6321 Fix Tauri listeners 2023-04-01 00:02:17 -07:00
Gregory Schier
dd99aa7fcd Memo editor 2023-03-31 23:19:15 -07:00
Gregory Schier
be436bb706 Fix request duplication 2023-03-31 22:54:32 -07:00
Gregory Schier
bd48726f44 Fix tauri listeners causing too many updates 2023-03-31 22:48:34 -07:00
Gregory Schier
10bea83f98 Remove import 2023-03-31 22:42:41 -07:00
Gregory Schier
8122b4fb84 Fix 2023-03-31 22:42:26 -07:00
Gregory Schier
3ae57fb2d8 Upgrade Deno 2023-03-31 22:42:08 -07:00
Gregory Schier
6dc3eecca4 Tweak 2023-03-31 16:14:25 -07:00
Gregory Schier
9d1d732154 Fix send hotkey 2023-03-31 16:13:34 -07:00
Gregory Schier
8a117415b7 Better schema fetching 2023-03-31 16:02:09 -07:00
Gregory Schier
d36623ebc9 Finally fix the editor! 2023-03-31 15:56:35 -07:00
Gregory Schier
94a3ae3696 Fix editor blurring bug! 2023-03-31 13:53:28 -07:00
Gregory Schier
2836a28988 Better model updates 2023-03-31 13:21:02 -07:00
Gregory Schier
946d7dc89e Fix text obscuring 2023-03-30 17:22:52 -07:00
Gregory Schier
af6300f18b Button ring colors 2023-03-30 17:17:07 -07:00
Gregory Schier
905cb4b18e Remove dummy button 2023-03-30 17:12:38 -07:00
Gregory Schier
305ed09547 Confirm deletions 2023-03-30 17:09:11 -07:00
Gregory Schier
643356bad3 Dedicated event for model creation 2023-03-30 16:49:49 -07:00
Gregory Schier
e458675627 Unify text selection color 2023-03-30 16:36:24 -07:00
Gregory Schier
91e3853692 Some icon tweaks 2023-03-30 16:29:14 -07:00
Gregory Schier
5f0876a136 Fix strict mode editor blur bug 2023-03-30 10:38:33 -07:00
Gregory Schier
3a38127fb4 Better tauri listeners and stuff 2023-03-30 09:05:54 -07:00
Gregory Schier
f3b6070235 Remove updated_by, remember last location 2023-03-30 08:11:51 -07:00
Gregory Schier
5e6e78eb9e Remove hardcoded window config 2023-03-29 22:16:21 -07:00
Gregory Schier
9b66a1d1a8 Fix build 2023-03-29 22:15:55 -07:00
Gregory Schier
e954d0d7bc Remove unused import 2023-03-29 21:53:49 -07:00
Gregory Schier
dab2df7e79 Better multi-window updates 2023-03-29 21:53:20 -07:00
Gregory Schier
bc40e22008 Fixed key/value stuff 2023-03-29 14:46:36 -07:00
Gregory Schier
eef262c398 Fix bundle parts 2023-03-29 14:00:34 -07:00
Gregory Schier
8eab6e14db Fix(ish) multiwindow updates 2023-03-29 11:15:37 -07:00
Gregory Schier
ded33a110a Obscure text 2023-03-29 10:16:51 -07:00
Gregory Schier
e448a7602a Simple auth schemes 2023-03-29 09:03:38 -07:00
Gregory Schier
4c22215ca5 Good start to multi-window 2023-03-28 18:29:40 -07:00
Gregory Schier
4f501abb72 Focus traps for dialog and dropdown 2023-03-26 23:07:09 -07:00
Gregory Schier
b2dcc38982 Confirmation Dialogs 2023-03-26 12:02:20 -07:00
Gregory Schier
11b719955b Floating sidebar 2023-03-26 10:09:28 -07:00
Gregory Schier
d563ac63db Panel icons 2023-03-25 23:29:04 -07:00
Gregory Schier
6d826064c6 Update dialog 2023-03-25 21:59:18 -07:00
Gregory Schier
d30b9d6518 Optimistically-update key values 2023-03-25 21:54:00 -07:00
Gregory Schier
8da3364d0f More tweaks 2023-03-25 21:40:14 -07:00
Gregory Schier
07c372b7f5 Animate dropdown 2023-03-25 21:36:17 -07:00
Gregory Schier
7e01f38253 Animate sidebar transition 2023-03-25 21:31:52 -07:00
Gregory Schier
ba637009a7 Refactor and improve layout resizing 2023-03-25 21:16:10 -07:00
Gregory Schier
da7388e510 Even better layouts 2023-03-25 18:33:01 -07:00
Gregory Schier
3ec88fc896 Better grid layouts 2023-03-25 18:12:09 -07:00
Gregory Schier
1c9381b2bd Global layout component 2023-03-25 13:26:31 -07:00
Gregory Schier
06349b8d5b Better dropdown separator 2023-03-25 11:06:05 -07:00
Gregory Schier
6dc7dc6ad2 Fix sidebar drag 2023-03-24 08:37:52 -07:00
Gregory Schier
f981a15ec3 Upgrade TYpescript 2023-03-23 15:37:36 -07:00
Gregory Schier
8b648c0301 Fix resize 2023-03-23 07:47:58 -07:00
Gregory Schier
83ce09075b Style tweak 2023-03-21 23:59:09 -07:00
Gregory Schier
168dfb9f6b GraphQL autocomplete and duplicate request 2023-03-21 23:54:45 -07:00
Gregory Schier
9b8961c23d Tweak sidebar drag resizer 2023-03-21 19:36:32 -07:00
Gregory Schier
89bca42ee6 Minor style tweaks 2023-03-21 18:31:05 -07:00
Gregory Schier
07d2a43a17 Pull out resize bar 2023-03-21 16:53:49 -07:00
Gregory Schier
c84f2afd09 Resize titlebar and tweak things 2023-03-21 16:42:52 -07:00
Gregory Schier
df4dbaecc8 Remove icon generation from build script 2023-03-21 14:21:07 -07:00
Gregory Schier
d9bf03cefe query client cache and better body types 2023-03-21 11:38:37 -07:00
Gregory Schier
39223e8d89 Fix workspace deletion 2023-03-21 09:32:15 -07:00
Gregory Schier
67925e18b2 Use proper gray for syntax 2023-03-20 17:15:12 -07:00
Gregory Schier
89ad65513d fix import 2023-03-20 17:13:14 -07:00
Gregory Schier
90166ddfa3 Minor tweaks 2023-03-20 17:12:19 -07:00
Gregory Schier
0981b23faf Fix URL bar spacing 2023-03-20 17:01:29 -07:00
Gregory Schier
664f3b4d87 Better radio dropdown type 2023-03-20 16:54:26 -07:00
Gregory Schier
dc97b91a4e Typesafe routing and CM line height issue 2023-03-20 16:47:36 -07:00
Gregory Schier
d310272d19 Better tab dropdown handling 2023-03-20 14:14:30 -07:00
Gregory Schier
f1be3f01e1 Fix request creation priority 2023-03-20 13:56:03 -07:00
Gregory Schier
c57b6e1d73 Remove log 2023-03-20 13:49:35 -07:00
Gregory Schier
a938dc45f0 Handle "no body" case 2023-03-20 13:49:21 -07:00
Gregory Schier
bb139744a1 Small fix 2023-03-20 13:37:14 -07:00
Gregory Schier
3aa3e09552 Fix pointer window drag 2023-03-20 13:34:49 -07:00
Gregory Schier
74abfd21b8 Fix extra dropdown element 2023-03-20 13:19:23 -07:00
Gregory Schier
e703817ba2 Remove most of Radix UI 2023-03-20 13:16:58 -07:00
Gregory Schier
80dd1e457b Better Header validation 2023-03-20 01:38:05 -07:00
Gregory Schier
ea9f8d3ab2 Tweak sidebar 2023-03-20 01:30:45 -07:00
Gregory Schier
fa222bdf12 Fix pair editor container 2023-03-20 01:18:44 -07:00
Gregory Schier
45b360dabd Fix input thingy 2023-03-20 01:14:13 -07:00
Gregory Schier
5923399359 Container queries! 2023-03-20 01:08:41 -07:00
Gregory Schier
f4600f3e90 Better pair editor delete button 2023-03-20 00:30:42 -07:00
Gregory Schier
f883837685 Pair validation 2023-03-20 00:17:29 -07:00
Gregory Schier
b58bc409f0 Don't send disabled headers 2023-03-20 00:05:19 -07:00
Gregory Schier
e893e539bb Small tweak 2023-03-20 00:04:40 -07:00
Gregory Schier
90294fbb5d Pair checkboxes and fix twig indent 2023-03-20 00:03:33 -07:00
Gregory Schier
ae65f222bc Rewrote twig grammar 2023-03-19 22:12:11 -07:00
Gregory Schier
1b9813fb4c Re-order of pair editor 2023-03-19 13:28:57 -07:00
Gregory Schier
b708b5ae41 Better header editor and added completion data 2023-03-19 11:09:21 -07:00
Gregory Schier
df136fa915 A couple tweaks 2023-03-19 01:01:13 -07:00
Gregory Schier
f8329f5b8d Persist sort priority! 2023-03-19 00:48:09 -07:00
Gregory Schier
21141090de Create new workspace, and more optimizations 2023-03-18 19:36:31 -07:00
Gregory Schier
c0d9740a7d Optimized a few components 2023-03-18 18:49:01 -07:00
Gregory Schier
afcf630443 Fix sidebar drag-n-drop 2023-03-18 18:09:36 -07:00
Gregory Schier
1fe2c9826a Got drag opacity working 2023-03-18 15:06:38 -07:00
Gregory Schier
7272b80a3f Good start to drag-n-drop sidebar! 2023-03-18 14:41:07 -07:00
Gregory Schier
92114b7368 Fix mixed parser 2023-03-17 17:57:43 -07:00
Gregory Schier
f39d3e7eed Dropdown highlight 2023-03-17 17:32:24 -07:00
Gregory Schier
cbe0d27a5e Beginnings of autocomplete for headers 2023-03-17 16:51:20 -07:00
Gregory Schier
cd39699467 Flatten migrations, kvs lib, fix tabs 2023-03-17 08:36:21 -07:00
Gregory Schier
b3ea67aacf Sidebar item dropdown 2023-03-16 15:37:53 -07:00
Gregory Schier
db4ed9797c Sidebar dragging 2023-03-16 14:34:49 -07:00
Gregory Schier
1ea7d7d685 Add devtools toggle hotkey 2023-03-16 11:25:38 -07:00
Gregory Schier
2df725b57a Adjust window sizes 2023-03-16 11:16:23 -07:00
Gregory Schier
74e6648249 Store appearance in k/v 2023-03-16 11:01:30 -07:00
Gregory Schier
1026350d9c Hotkeys and view mode kvs 2023-03-16 09:24:28 -07:00
Gregory Schier
98fb87874d Some fixes 2023-03-15 23:33:46 -07:00
Gregory Schier
41fc3afdc1 Got key values working 2023-03-15 23:24:41 -07:00
Gregory Schier
83dbf46ba4 Fix editor padding 2023-03-15 17:29:35 -07:00
Gregory Schier
0b2e35bdde Minor style updates 2023-03-15 17:25:04 -07:00
Gregory Schier
d90a7331c9 Add stuff to app header 2023-03-15 16:35:19 -07:00
Gregory Schier
264e64a996 Better request delete and formatting 2023-03-15 09:41:38 -07:00
Gregory Schier
8915915c47 Fix graphql and other things 2023-03-15 09:06:56 -07:00
Gregory Schier
951ed787fa Header editor to pair editor 2023-03-15 08:09:45 -07:00
Gregory Schier
64ef6b0c22 Better header editor 2023-03-15 07:54:04 -07:00
Gregory Schier
ef18377b3c Strict mode and tweak layout padding 2023-03-14 20:19:45 -07:00
Gregory Schier
5904b6fded Add GraphQL variables editor 2023-03-14 19:56:02 -07:00
Gregory Schier
f4401e77bb GraphQL query editor transformer works! 2023-03-14 19:08:18 -07:00
Gregory Schier
efa5455a7b Add body type to request and tab dropdown 2023-03-14 11:18:56 -07:00
Gregory Schier
619c8d9e72 Improved header editor 2023-03-14 00:54:41 -07:00
Gregory Schier
bdf89ac288 Fix platform check 2023-03-14 00:15:01 -07:00
Gregory Schier
debd3c8185 Some small changes 2023-03-14 00:08:03 -07:00
Gregory Schier
f81a3ae8e7 Move stuff around 2023-03-13 23:30:14 -07:00
Gregory Schier
7d4e9894c3 Refactor hooks to be easier to use 2023-03-13 23:25:41 -07:00
Gregory Schier
4bf22d8a60 Fix header editor and scroll in general 2023-03-13 19:37:36 -07:00
Gregory Schier
8be4971a23 Lazy load routes 2023-03-13 13:56:13 -07:00
Gregory Schier
359e916b73 Back to React 2023-03-13 09:50:49 -07:00
Gregory Schier
68058f3e41 Move some stuff around 2023-03-13 09:24:38 -07:00
Gregory Schier
0c6fa3e634 Fix URL bar 2023-03-13 00:13:25 -07:00
Gregory Schier
0fa25c6335 Fix ButtonLink and edit request names 2023-03-13 00:11:23 -07:00
Gregory Schier
5684479f1d Remove old rust cache action 2023-03-12 22:48:43 -07:00
Gregory Schier
2d1603601c Better rust cache 2023-03-12 22:47:43 -07:00
Gregory Schier
f5394b2210 Start GraphQL support 2023-03-12 22:43:25 -07:00
Gregory Schier
833db5df06 Fix artifact tag 2023-03-12 21:41:15 -07:00
Gregory Schier
525ac7e980 Remove wasm stuff 2023-03-12 21:25:31 -07:00
Gregory Schier
44a747c80a Use tauri action 2023-03-12 21:13:08 -07:00
Gregory Schier
2056e7f40a Fix traffic lights thingy 2023-03-12 20:47:52 -07:00
Gregory Schier
9b6c1ad364 Cache cargo bin for "install" 2023-03-12 19:10:39 -07:00
Gregory Schier
34987bcacb Refformat 2023-03-12 19:03:27 -07:00
Gregory Schier
b62c11222a Fix artifact upload 2023-03-12 19:01:48 -07:00
Gregory Schier
b3cee3ace3 Fix dev 2023-03-12 18:39:02 -07:00
Gregory Schier
222c054c95 Split out macos deps 2023-03-12 18:36:25 -07:00
Gregory Schier
46f18a2491 Cache workflow 2023-03-12 18:28:14 -07:00
Gregory Schier
f2ca8e2753 Add wasm-pack 2023-03-12 18:19:20 -07:00
Gregory Schier
b0d243c378 Install rsw 2023-03-12 18:14:38 -07:00
Gregory Schier
6161fb86c8 Fix artifact names 2023-03-12 18:13:00 -07:00
Gregory Schier
b09cc91fe5 Fix build command 2023-03-12 18:11:24 -07:00
Gregory Schier
ef1638cbb3 Update secrets context 2023-03-12 18:07:57 -07:00
Gregory Schier
00ef8743f2 Update workflow name 2023-03-12 18:05:45 -07:00
Gregory Schier
68222659e3 Fix workflow 2023-03-12 18:05:13 -07:00
Gregory Schier
69420a4bba Start of auto updates 2023-03-12 18:04:11 -07:00
Gregory Schier
0161bbaeb1 Fix tabbing to tabs 2023-03-11 23:32:39 -08:00
Gregory Schier
948dbfe3cc Fix eslint errors 2023-03-11 23:29:25 -08:00
Gregory Schier
338ba8b189 Got tab content scrolling working 2023-03-11 22:36:13 -08:00
Gregory Schier
ca4655b441 Removed some debug stuff 2023-03-10 10:43:15 -08:00
Gregory Schier
bf37499428 Refactor editor to update better 2023-03-10 10:39:23 -08:00
Gregory Schier
0b94b57e2a Fix headers persistence and better sending 2023-03-09 13:38:17 -08:00
Gregory Schier
fc40aead98 Hook up header editor! 2023-03-09 13:07:13 -08:00
Gregory Schier
7d7f934e6a Fix 2023-03-09 10:58:27 -08:00
Gregory Schier
d5fbf4d622 Fix blur de-select speed 2023-03-09 10:57:34 -08:00
Gregory Schier
e4f6c919dc Fix Codemirror performance!! 2023-03-09 10:50:55 -08:00
Gregory Schier
4d806ff2b1 Switch to Preact!!! 2023-03-09 00:47:25 -08:00
Gregory Schier
bf8f12274f Move some things around 2023-03-08 23:20:15 -08:00
Gregory Schier
f4f438d9fe Better scrollbar color 2023-03-08 19:23:24 -08:00
Gregory Schier
2434f373be Zoom, better sizes, color picker, sidebar footer 2023-03-08 19:22:04 -08:00
Gregory Schier
2bb2061f97 Read-only editor 2023-03-08 16:53:13 -08:00
Gregory Schier
2c011a5c2a More theme tweaks 2023-03-08 16:37:20 -08:00
Gregory Schier
f66b0ccea1 Debounce autocomplete 2023-03-08 11:25:20 -08:00
Gregory Schier
665dd8447d Minor theme updates again 2023-03-08 09:43:35 -08:00
Gregory Schier
1b61ce31e6 Editor tweaks 2023-03-07 23:05:33 -08:00
Gregory Schier
ef4d960698 Remove unneeded space 2023-03-07 22:58:13 -08:00
Gregory Schier
b6d557b632 Fix small view 2023-03-07 22:55:51 -08:00
Gregory Schier
b700bd356c Minor style tweaks 2023-03-07 22:21:58 -08:00
Gregory Schier
620dd7d3ef Lots more theme stuff 2023-03-07 21:52:21 -08:00
Gregory Schier
6575121902 Start of themes 2023-03-07 11:24:38 -08:00
Gregory Schier
7c1755a0dc More subtle layout tweaks 2023-03-06 08:57:57 -08:00
Gregory Schier
8ad301a666 More layout fiddling and error page 2023-03-04 22:26:00 -08:00
Gregory Schier
ae24cd4939 More work on the layout 2023-03-04 21:51:17 -08:00
Gregory Schier
7152e1845e Try new layout and a bunch of editor fixes 2023-03-04 19:06:12 -08:00
Gregory Schier
96c1dd4081 Fix autocomplete inside dialog 2023-03-03 17:03:20 -08:00
Gregory Schier
87c7b3a663 Beginnings of Header Editor 2023-03-03 13:18:57 -08:00
Gregory Schier
c1be46a539 Fix tailwind dark selector 2023-03-03 07:54:19 -08:00
Gregory Schier
4655e0018b Fix content type in URL 2023-03-02 23:17:09 -08:00
Gregory Schier
da5ba2e3be Add Dialog component 2023-03-02 18:46:10 -08:00
Gregory Schier
aaf95f565f More colors 2023-03-02 17:56:53 -08:00
Gregory Schier
f32b984e77 Minor style tweaks 2023-03-02 16:16:41 -08:00
Gregory Schier
548aa4c7cd Improved autocompletion! 2023-03-02 11:14:51 -08:00
Gregory Schier
0ccceaac77 Rename, fix autocomplete and singleline, etc... 2023-03-02 10:42:43 -08:00
Gregory Schier
70f534f1d8 Editor placeholder 2023-03-01 14:22:10 -08:00
Gregory Schier
61fe95b300 Some minor bugs 2023-03-01 14:16:02 -08:00
Gregory Schier
915e0e8613 Fix migrations for build and iframe rendering 2023-03-01 10:31:50 -08:00
Gregory Schier
aace2580da Tweaks 2023-03-01 10:19:21 -08:00
Gregory Schier
3d36905664 Response streaming 2023-03-01 09:05:00 -08:00
Gregory Schier
0d671423da Autocomplete, and more CM stuff! 2023-02-28 22:54:54 -08:00
Gregory Schier
aebfcb9437 Some small tweaks 2023-02-28 17:25:59 -08:00
Gregory Schier
be7ef7beb1 Better editor updating 2023-02-28 12:41:03 -08:00
Gregory Schier
d77ed0c5cc URL highlighting with inline CM 2023-02-28 11:26:26 -08:00
Gregory Schier
e57e7bcec5 Implement request deletion 2023-02-27 15:42:06 -08:00
Gregory Schier
a637842ce4 Tauri events for request model updates 2023-02-27 13:28:50 -08:00
Gregory Schier
fc54ec49af Split request upsert command 2023-02-27 10:00:57 -08:00
Gregory Schier
5c43d8510a Add toggle for pretty view 2023-02-27 09:08:48 -08:00
Gregory Schier
83f84ded8d Small tweaks 2023-02-26 15:25:55 -08:00
Gregory Schier
5658da34a2 Add variable highlighting widgets 2023-02-26 15:06:14 -08:00
Gregory Schier
38e8ef6535 Dropdown scrolling 2023-02-25 23:33:07 -08:00
Gregory Schier
8c89b06238 Show response body size 2023-02-25 23:08:19 -08:00
Gregory Schier
d85c021305 A bunch more small things 2023-02-25 23:04:31 -08:00
Gregory Schier
83bb18df03 Added react-router 2023-02-25 18:04:14 -08:00
Gregory Schier
93105a3e89 Migrations and initial data stuff 2023-02-25 16:39:18 -08:00
Gregory Schier
ba3b899115 Minor tweaks 2023-02-24 17:01:48 -08:00
Gregory Schier
fcfbc1d1da Dummy requests in sidebar 2023-02-24 16:46:56 -08:00
Gregory Schier
72486b448c Codemirror initial value support 2023-02-24 16:43:47 -08:00
Gregory Schier
7dea1b7870 Send request body 2023-02-24 16:09:19 -08:00
Gregory Schier
4de2c496c9 Vendor basicSetup 2023-02-24 14:51:56 -08:00
Gregory Schier
9e1393a392 Additional methods and tweaks 2023-02-24 14:10:25 -08:00
Gregory Schier
0901690ed6 Focus states 2023-02-24 12:35:13 -08:00
Gregory Schier
95303648cc Hook up theme and clear responses 2023-02-24 12:13:30 -08:00
Gregory Schier
1dbb08c045 SQLite store in proper dir 2023-02-22 20:18:14 -08:00
Gregory Schier
00a7d9a180 Started on grid layout 2023-02-22 19:44:44 -08:00
Gregory Schier
6c549dc086 Save responses in DB 2023-02-22 18:53:44 -08:00
Gregory Schier
dc368e326a Better URL bar 2023-02-22 16:15:25 -08:00
Gregory Schier
e42188a627 Cleaner URL bar and some improvements 2023-02-22 15:58:04 -08:00
Gregory Schier
7a6a337eff Refactor classname usage 2023-02-21 18:03:57 -08:00
Gregory Schier
3907344884 Some minor tweaks 2023-02-21 17:56:48 -08:00
213 changed files with 4114 additions and 19810 deletions

View File

@@ -3,6 +3,8 @@ on:
push:
tags: [ v* ]
permissions: write-all
jobs:
build-artifacts:
permissions:
@@ -21,28 +23,34 @@ jobs:
- platform: 'windows-latest'
args: ''
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v4
- name: setup node
uses: actions/setup-node@v4
with:
node-version: lts/*
- name: install Rust stable
uses: dtolnay/rust-toolchain@stable
with:
# Those targets are only used on macos runners so it's in an `if` to slightly speed up windows and linux builds.
targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
- name: install dependencies (ubuntu only)
if: matrix.platform == 'ubuntu-22.04' # This must match the platform value defined above.
run: |
sudo apt-get update
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
sudo apt-get install -y libwebkit2gtk-4.0-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
# webkitgtk 4.0 is for Tauri v1 - webkitgtk 4.1 is for Tauri v2.
# You can remove the one that doesn't apply to your app to speed up the workflow a bit.
- name: Install dependencies
run: npm ci
- name: Run lint
run: npm run lint
- name: Run tests
run: npm test
- uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -0,0 +1,20 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Build Desktop" type="ShConfigurationType">
<option name="SCRIPT_TEXT" value="npm run tauri build -- --target universal-apple-darwin" />
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
<option name="SCRIPT_PATH" value="" />
<option name="SCRIPT_OPTIONS" value="" />
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
<option name="INTERPRETER_PATH" value="/bin/zsh" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="EXECUTE_IN_TERMINAL" value="true" />
<option name="EXECUTE_SCRIPT_FILE" value="false" />
<envs>
<env name="TAURI_KEY_PASSWORD" value="fishhook-upstream-wash-assured" />
<env name="TAURI_PRIVATE_KEY" value="dW50cnVzdGVkIGNvbW1lbnQ6IHJzaWduIGVuY3J5cHRlZCBzZWNyZXQga2V5ClJXUlRZMEl5OGxWaytTa3dIa2xXVUltQzRGUXIzd2lYQ2NpV0ZhQURSbWJWZ1NrK0tnY0FBQkFBQUFBQUFBQUFBQUlBQUFBQUV2M1VKdVRyVHpHSzhQdGc2ZVFtOVNsMU5tNEVSN280cFNrbXhncW9tdjNXaFJZUTJqUzQ5Q01zWTJWRVhaY1pGNHNjR1NFR3JmcWFRN09NdWdGMXpZVXhzejR4V3lDV1JpZHlnbW5LNS9vMFFtRlZjbUl4YjZSNzhlMmk3ait5SExYcG5QZUkxOFE9Cg==" />
</envs>
<method v="2" />
</configuration>
</component>

1
.tauriignore Normal file
View File

@@ -0,0 +1 @@
plugins

View File

@@ -1,8 +1,8 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Yaak App</title>
<!-- <script src="http://localhost:8097"></script>-->
@@ -15,13 +15,13 @@
@media (prefers-color-scheme: dark) {
html, body {
background-color: #1b1a29;
background-color: black;
}
}
</style>
</head>
<body class="text-base">
<body>
<div id="root"></div>
<div id="cm-portal" class="cm-portal"></div>
<div id="react-portal"></div>

90
package-lock.json generated
View File

@@ -9,7 +9,7 @@
"version": "0.0.0",
"dependencies": {
"@codemirror/commands": "^6.2.1",
"@codemirror/lang-javascript": "^6.2.2",
"@codemirror/lang-javascript": "^6.1.4",
"@codemirror/lang-json": "^6.0.1",
"@codemirror/lang-xml": "^6.0.2",
"@codemirror/language": "^6.6.0",
@@ -81,7 +81,7 @@
"prettier": "^2.8.4",
"react-devtools": "^4.27.2",
"tailwindcss": "^3.2.7",
"typescript": "^5.4.5",
"typescript": "^5.3.3",
"vite": "^5.0.0",
"vite-plugin-svgr": "^4.2.0",
"vite-plugin-top-level-await": "^1.4.1",
@@ -2309,9 +2309,9 @@
}
},
"node_modules/@tauri-apps/cli": {
"version": "2.0.0-beta.20",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.0.0-beta.20.tgz",
"integrity": "sha512-707q9uIc2oNrYHd2dtMvxTrpZXVpart5EIktnRymNOpphkLlB6WUBjHD+ga45WqTU6cNGKbYvkKqTNfshNul9Q==",
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.0.0-beta.15.tgz",
"integrity": "sha512-3pCvc54QfsRY+i9B7w3Q5jPAGtf8p+g7N/BamWPeiW6YqDqbHi9rNVI3SzrHkRRNOJnzMW8E5a8G0HziOluZGg==",
"dev": true,
"bin": {
"tauri": "tauri.js"
@@ -2324,22 +2324,22 @@
"url": "https://opencollective.com/tauri"
},
"optionalDependencies": {
"@tauri-apps/cli-darwin-arm64": "2.0.0-beta.20",
"@tauri-apps/cli-darwin-x64": "2.0.0-beta.20",
"@tauri-apps/cli-linux-arm-gnueabihf": "2.0.0-beta.20",
"@tauri-apps/cli-linux-arm64-gnu": "2.0.0-beta.20",
"@tauri-apps/cli-linux-arm64-musl": "2.0.0-beta.20",
"@tauri-apps/cli-linux-x64-gnu": "2.0.0-beta.20",
"@tauri-apps/cli-linux-x64-musl": "2.0.0-beta.20",
"@tauri-apps/cli-win32-arm64-msvc": "2.0.0-beta.20",
"@tauri-apps/cli-win32-ia32-msvc": "2.0.0-beta.20",
"@tauri-apps/cli-win32-x64-msvc": "2.0.0-beta.20"
"@tauri-apps/cli-darwin-arm64": "2.0.0-beta.15",
"@tauri-apps/cli-darwin-x64": "2.0.0-beta.15",
"@tauri-apps/cli-linux-arm-gnueabihf": "2.0.0-beta.15",
"@tauri-apps/cli-linux-arm64-gnu": "2.0.0-beta.15",
"@tauri-apps/cli-linux-arm64-musl": "2.0.0-beta.15",
"@tauri-apps/cli-linux-x64-gnu": "2.0.0-beta.15",
"@tauri-apps/cli-linux-x64-musl": "2.0.0-beta.15",
"@tauri-apps/cli-win32-arm64-msvc": "2.0.0-beta.15",
"@tauri-apps/cli-win32-ia32-msvc": "2.0.0-beta.15",
"@tauri-apps/cli-win32-x64-msvc": "2.0.0-beta.15"
}
},
"node_modules/@tauri-apps/cli-darwin-arm64": {
"version": "2.0.0-beta.20",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.0.0-beta.20.tgz",
"integrity": "sha512-oCJOCib7GuYkwkBXx+ekamR8NZZU+2i3MLP+DHpDxK5gS2uhCE+CBkamJkNt6y1x6xdVnwyqZOm5RvN4SRtyIA==",
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.0.0-beta.15.tgz",
"integrity": "sha512-M4owBLoRdJb2/IK48KOQDU3j5xrjqGxa539rDXMjvaKydBk8x+aLdk3xZNsk/owHTI1GnrQZsPCMQaOgetYHaw==",
"cpu": [
"arm64"
],
@@ -2353,9 +2353,9 @@
}
},
"node_modules/@tauri-apps/cli-darwin-x64": {
"version": "2.0.0-beta.20",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.0.0-beta.20.tgz",
"integrity": "sha512-lC5QSnRExedYN4Ds6ZlSvC2PxP8qfIYBJQ5ktf+PJI5gQALdNeVtd6YnTG1ODCEklfLq9WKkGwp7JdALTU5wDA==",
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.0.0-beta.15.tgz",
"integrity": "sha512-ECpatfJdT4xKyFoE7tNEtTUIRxjQ2XSXa0TQkP3g7Kn7H/jRse+7pYe69jASA7shixajatAwmD4bXNT8jYRyNA==",
"cpu": [
"x64"
],
@@ -2369,9 +2369,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-arm-gnueabihf": {
"version": "2.0.0-beta.20",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.0.0-beta.20.tgz",
"integrity": "sha512-nZCeBMHHye5DLOJV5k2w658hnCS+LYaOZ8y/G9l3ei+g0L/HBjlSy6r4simsAT5TG8+l3oCZzLBngfTMdDS/YA==",
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.0.0-beta.15.tgz",
"integrity": "sha512-GQz2nnPwIamzDbmmfGWvmmoLthOkOBs0RO5u72KYAa78ZRFTx7S6AovnxJv48Fq+zeGGdDKoD9+ZG2Ue+sCL4w==",
"cpu": [
"arm"
],
@@ -2385,9 +2385,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-arm64-gnu": {
"version": "2.0.0-beta.20",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.0.0-beta.20.tgz",
"integrity": "sha512-B79ISVLPVBgwnCchVqwTKU+vxnFYqxKomcR4rmsvxfs0NVtT5QuNzE1k4NUQnw3966yjwhYR3mnHsSJQSB4Eyw==",
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.0.0-beta.15.tgz",
"integrity": "sha512-YBIfq0GbmIsWmRy6dVuDv3oMJN7a3R8HGVPMsa1W526AdCxoZDiPOQpSQN4VihJlbebUHxS/HyYF6maCY8uGzA==",
"cpu": [
"arm64"
],
@@ -2401,9 +2401,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-arm64-musl": {
"version": "2.0.0-beta.20",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.0.0-beta.20.tgz",
"integrity": "sha512-ojIkv/1uZHhcrgfIN8xgn4BBeo/Xg+bnV0wer6lD78zyxkUMWeEZ+u3mae1ejCJNhhaZOxNaUQ67MvDOiGyr5Q==",
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.0.0-beta.15.tgz",
"integrity": "sha512-2ZBXoShz7UfqVGmc85mhwjI6ckdtrk15V69adxt/x+VS68yK6Ddbj+yqlffpeFNL90fZrsVhFoRIDqgkxtwksQ==",
"cpu": [
"arm64"
],
@@ -2417,9 +2417,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-x64-gnu": {
"version": "2.0.0-beta.20",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.0.0-beta.20.tgz",
"integrity": "sha512-xBy1FNbHKlc7T6pOmFQQPECxJaI5A9QWX7Kb9N64cNVusoOGlvc3xHYkXMS4PTr7xXOT0yiE1Ww2OwDRJ3lYsg==",
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.0.0-beta.15.tgz",
"integrity": "sha512-cwJqIIdc4Kq9sBl/vYc+Y95iMe+mlTYUj7ZnSn4YAbLKFz432bGg6uBn2qHXFN5jzwXtEOVZiB1zDZ2kveVoAQ==",
"cpu": [
"x64"
],
@@ -2433,9 +2433,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-x64-musl": {
"version": "2.0.0-beta.20",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.0.0-beta.20.tgz",
"integrity": "sha512-+O6zq5jmtUxA1FUAAwF2ywPysy4NRo2Y6G+ESZDkY9XosRwdt5OUjqAsYktZA3AxDMZVei8r9buwTqUwi9ny/g==",
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.0.0-beta.15.tgz",
"integrity": "sha512-nNuxZ8/qs0vQbdLO2hovskZGxwGn2z4x1QFJuL4xwd6Tryy9vVcznvyZS+t/72dCLoIkY9pKZQq5nYtAHYfTEg==",
"cpu": [
"x64"
],
@@ -2449,9 +2449,9 @@
}
},
"node_modules/@tauri-apps/cli-win32-arm64-msvc": {
"version": "2.0.0-beta.20",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.0.0-beta.20.tgz",
"integrity": "sha512-RswgMbWyOQcv53CHvIuiuhAh4kKDqaGyZfWD4VlxqX/XhkoF5gsNgr0MxzrY7pmoL+89oVI+fiGVJz4nOQE5vA==",
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.0.0-beta.15.tgz",
"integrity": "sha512-DXiXMTE00INjBkTgq1CYduMWgUwQ0NvLw+uXfu8BUupA+aOlv9ODhsGu7bZSaxKx4/glwxNAGZum4kQ0E0AxUg==",
"cpu": [
"arm64"
],
@@ -2465,9 +2465,9 @@
}
},
"node_modules/@tauri-apps/cli-win32-ia32-msvc": {
"version": "2.0.0-beta.20",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.0.0-beta.20.tgz",
"integrity": "sha512-5lgWmDVXhX3SBGbiv5SduM1yajiRnUEJClWhSdRrEEJeXdsxpCsBEhxYnUnDCEzPKxLLn5fdBv3VrVctJ03csQ==",
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.0.0-beta.15.tgz",
"integrity": "sha512-ajEQdW2jx2raPp7eDYryJkbBrgI8PIY1dz5ro8FweRrRmbotaUlclsro1kfNMQrfDah8+qfwnRvW3MahOBE5Wg==",
"cpu": [
"ia32"
],
@@ -2481,9 +2481,9 @@
}
},
"node_modules/@tauri-apps/cli-win32-x64-msvc": {
"version": "2.0.0-beta.20",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.0.0-beta.20.tgz",
"integrity": "sha512-SuSiiVQTQPSzWlsxQp/NMzWbzDS9TdVDOw7CCfgiG5wnT2GsxzrcIAVN6i7ILsVFLxrjr0bIgPldSJcdcH84Yw==",
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.0.0-beta.15.tgz",
"integrity": "sha512-yzsSgoiY0PmFiR5LvVOFr1b7h9l3aLPPQFlDG6+kRMrxCo7x7Pbyh4D5cqiMUuZO0QacwSP38EH6w0F88Y+4OA==",
"cpu": [
"x64"
],

View File

@@ -4,9 +4,9 @@
"version": "0.0.0",
"type": "module",
"scripts": {
"start": "npm run tauri-dev:desktop",
"start": "npm run build:plugins && npm run tauri-dev:desktop",
"tauri-dev:desktop": "tauri dev --no-watch --config ./src-tauri/tauri-dev.conf.json",
"tauri-dev:ios": "tauri ios dev --force-ip-prompt --config ./src-tauri/tauri-dev.conf.json",
"tauri-dev:ios": "tauri ios dev --no-watch --config ./src-tauri/tauri-dev.conf.json",
"tauri-build": "tauri build",
"tauri": "tauri",
"build": "npm run build:frontend",
@@ -29,7 +29,7 @@
},
"dependencies": {
"@codemirror/commands": "^6.2.1",
"@codemirror/lang-javascript": "^6.2.2",
"@codemirror/lang-javascript": "^6.1.4",
"@codemirror/lang-json": "^6.0.1",
"@codemirror/lang-xml": "^6.0.2",
"@codemirror/language": "^6.6.0",
@@ -101,7 +101,7 @@
"prettier": "^2.8.4",
"react-devtools": "^4.27.2",
"tailwindcss": "^3.2.7",
"typescript": "^5.4.5",
"typescript": "^5.3.3",
"vite": "^5.0.0",
"vite-plugin-svgr": "^4.2.0",
"vite-plugin-top-level-await": "^1.4.1",

View File

@@ -80,26 +80,6 @@ describe('exporter-curl', () => {
);
});
test('Exports multi-line JSON body', () => {
expect(
pluginHookExport({
url: 'https://yaak.app',
method: 'POST',
bodyType: 'application/json',
body: {
text: `{"foo":"bar",\n"baz":"qux"}`,
},
headers: [{ name: 'Content-Type', value: 'application/json' }],
}),
).toEqual(
[
`curl -X POST 'https://yaak.app'`,
`--header 'Content-Type: application/json'`,
`--data-raw $'{"foo":"bar",\n"baz":"qux"}'`,
].join(` \\\n `),
);
});
test('Exports headers', () => {
expect(
pluginHookExport({

View File

@@ -52,7 +52,7 @@ export function pluginHookImport(rawData: string) {
// Replace non-escaped newlines with semicolons to make parsing easier
// NOTE: This is really slow in debug build but fast in release mode
const normalizedData = rawData.replace(/\ncurl/g, '; curl');
const normalizedData = rawData.replace(/([^\\])\n/g, '$1; ');
let currentCommand: ParseEntry[] = [];
@@ -137,6 +137,8 @@ export function importCommand(parseEntries: ParseEntry[], workspaceId: string) {
// Start at 1 so we can skip the ^curl part
for (let i = 1; i < parseEntries.length; i++) {
let parseEntry = parseEntries[i];
// trim leading spaces between parsed entries
// regex won't match otherwise (e.g. -H 'Content-Type: application/json')
if (typeof parseEntry === 'string') {
parseEntry = parseEntry.trim();
}
@@ -184,7 +186,7 @@ export function importCommand(parseEntries: ParseEntry[], workspaceId: string) {
urlParameters =
search?.split('&').map((p) => {
const v = splitOnce(p, '=');
return { name: v[0] ?? '', value: v[1] ?? '', enabled: true };
return { name: v[0] ?? '', value: v[1] ?? '' };
}) ?? [];
url = baseUrl ?? urlArg;
@@ -212,13 +214,11 @@ export function importCommand(parseEntries: ParseEntry[], workspaceId: string) {
return {
name: (name ?? '').trim().replace(/;$/, ''),
value: '',
enabled: true,
};
}
return {
name: (name ?? '').trim(),
value: value.trim(),
enabled: true,
};
});
@@ -245,7 +245,6 @@ export function importCommand(parseEntries: ParseEntry[], workspaceId: string) {
headers.push({
name: 'Cookie',
value: cookieHeaderValue,
enabled: true,
});
}
@@ -289,17 +288,12 @@ export function importCommand(parseEntries: ParseEntry[], workspaceId: string) {
) {
bodyType = mimeType ?? 'application/x-www-form-urlencoded';
body = {
form: dataParameters.map((parameter) => ({
params: dataParameters.map((parameter) => ({
...parameter,
name: decodeURIComponent(parameter.name || ''),
value: decodeURIComponent(parameter.value || ''),
})),
};
headers.push({
name: 'Content-Type',
value: 'application/x-www-form-urlencoded',
enabled: true,
});
} else if (dataParameters.length > 0) {
bodyType =
mimeType === 'application/json' || mimeType === 'text/xml' || mimeType === 'text/plain'
@@ -315,20 +309,13 @@ export function importCommand(parseEntries: ParseEntry[], workspaceId: string) {
body = {
form: formDataParams,
};
if (mimeType == null) {
headers.push({
name: 'Content-Type',
value: 'multipart/form-data',
enabled: true,
});
}
}
// Method
let method = getPairValue(pairsByName, '', ['X', 'request']).toUpperCase();
if (method === '' && body) {
method = 'text' in body || 'form' in body ? 'POST' : 'GET';
method = 'text' in body || 'params' in body ? 'POST' : 'GET';
}
const request: ExportResources['httpRequests'][0] = {
@@ -357,7 +344,6 @@ const pairsToDataParameters = (keyedPairs: PairsByName) => {
value: string;
contentType?: string;
filePath?: string;
enabled?: boolean;
}[] = [];
for (const flagName of DATA_FLAGS) {
@@ -377,13 +363,11 @@ const pairsToDataParameters = (keyedPairs: PairsByName) => {
name: name ?? '',
value: '',
filePath: p.slice(1),
enabled: true,
});
} else {
dataParameters.push({
name: name ?? '',
value: flagName === 'data-urlencode' ? encodeURIComponent(value ?? '') : value ?? '',
enabled: true,
});
}
}

View File

@@ -122,13 +122,6 @@ describe('importer-curl', () => {
baseRequest({
method: 'POST',
url: 'https://yaak.app',
headers: [
{
name: 'Content-Type',
value: 'multipart/form-data',
enabled: true,
},
],
bodyType: 'multipart/form-data',
body: {
form: [
@@ -152,18 +145,11 @@ describe('importer-curl', () => {
method: 'POST',
url: 'https://yaak.app',
bodyType: 'application/x-www-form-urlencoded',
headers: [
{
name: 'Content-Type',
value: 'application/x-www-form-urlencoded',
enabled: true,
},
],
body: {
form: [
{ name: 'a', value: '', enabled: true },
{ name: 'b', value: '', enabled: true },
{ name: 'c', value: 'ccc', enabled: true },
params: [
{ name: 'a', value: '' },
{ name: 'b', value: '' },
{ name: 'c', value: 'ccc' },
],
},
}),
@@ -182,7 +168,7 @@ describe('importer-curl', () => {
baseRequest({
method: 'POST',
url: 'https://yaak.app',
headers: [{ name: 'Content-Type', value: 'text/plain', enabled: true }],
headers: [{ name: 'Content-Type', value: 'text/plain' }],
bodyType: 'text/plain',
body: { text: 'a&b&c=ccc' },
}),
@@ -191,27 +177,6 @@ describe('importer-curl', () => {
});
});
test('Imports multi-line JSON', () => {
expect(
pluginHookImport(
`curl -H Content-Type:application/json -d $'{\n "foo":"bar"\n}' https://yaak.app`,
),
).toEqual({
resources: {
workspaces: [baseWorkspace()],
httpRequests: [
baseRequest({
method: 'POST',
url: 'https://yaak.app',
headers: [{ name: 'Content-Type', value: 'application/json', enabled: true }],
bodyType: 'application/json',
body: { text: '{\n "foo":"bar"\n}' },
}),
],
},
});
});
test('Imports multiple headers', () => {
expect(
pluginHookImport('curl -H Foo:bar --header Name -H AAA:bbb -H :ccc https://yaak.app'),
@@ -222,10 +187,10 @@ describe('importer-curl', () => {
baseRequest({
url: 'https://yaak.app',
headers: [
{ name: 'Name', value: '', enabled: true },
{ name: 'Foo', value: 'bar', enabled: true },
{ name: 'AAA', value: 'bbb', enabled: true },
{ name: '', value: 'ccc', enabled: true },
{ name: 'Name', value: '' },
{ name: 'Foo', value: 'bar' },
{ name: 'AAA', value: 'bbb' },
{ name: '', value: 'ccc' },
],
}),
],
@@ -276,7 +241,7 @@ describe('importer-curl', () => {
httpRequests: [
baseRequest({
url: 'https://yaak.app',
headers: [{ name: 'Cookie', value: 'foo=bar', enabled: true }],
headers: [{ name: 'Cookie', value: 'foo=bar' }],
}),
],
},
@@ -291,8 +256,8 @@ describe('importer-curl', () => {
baseRequest({
url: 'https://yaak.app',
urlParameters: [
{ name: 'foo', value: 'bar', enabled: true },
{ name: 'baz', value: 'a%20a', enabled: true },
{ name: 'foo', value: 'bar' },
{ name: 'baz', value: 'a%20a' },
],
}),
],

View File

@@ -180,7 +180,6 @@ function importBody(rawBody: any): Pick<HttpRequest, 'body' | 'bodyType' | 'head
f.src != null
? {
enabled: !f.disabled,
contentType: f.contentType ?? null,
name: f.key ?? '',
file: f.src ?? '',
}
@@ -245,7 +244,6 @@ function convertTemplateSyntax<T>(obj: T): T {
}
const idCount: Partial<Record<Model['model'], number>> = {};
function generateId(model: Model['model']): string {
idCount[model] = (idCount[model] ?? -1) + 1;
return `GENERATE_ID::${model.toUpperCase()}_${idCount[model]}`;

View File

@@ -0,0 +1,12 @@
{
"db_name": "SQLite",
"query": "\n UPDATE settings SET (\n theme, appearance, update_channel\n ) = (?, ?, ?) WHERE id = 'default';\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 3
},
"nullable": []
},
"hash": "48ec5fdf20f34add763c540061caa25054545503704e19f149987f99b1a0e4f0"
}

View File

@@ -0,0 +1,56 @@
{
"db_name": "SQLite",
"query": "\n SELECT\n id, model, created_at, updated_at, theme, appearance, update_channel\n FROM settings\n WHERE id = 'default'\n ",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "model",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "created_at",
"ordinal": 2,
"type_info": "Datetime"
},
{
"name": "updated_at",
"ordinal": 3,
"type_info": "Datetime"
},
{
"name": "theme",
"ordinal": 4,
"type_info": "Text"
},
{
"name": "appearance",
"ordinal": 5,
"type_info": "Text"
},
{
"name": "update_channel",
"ordinal": 6,
"type_info": "Text"
}
],
"parameters": {
"Right": 0
},
"nullable": [
false,
false,
false,
false,
false,
false,
false
]
},
"hash": "b32994b09ae7a06eb0f031069d327e55127a5bce60cbb499b83d1701386a23cb"
}

View File

@@ -1,92 +0,0 @@
{
"db_name": "SQLite",
"query": "\n SELECT\n id, model, created_at, updated_at, theme, appearance,\n theme_dark, theme_light, update_channel,\n interface_font_size, interface_scale, editor_font_size, editor_soft_wrap\n FROM settings\n WHERE id = 'default'\n ",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "model",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "created_at",
"ordinal": 2,
"type_info": "Datetime"
},
{
"name": "updated_at",
"ordinal": 3,
"type_info": "Datetime"
},
{
"name": "theme",
"ordinal": 4,
"type_info": "Text"
},
{
"name": "appearance",
"ordinal": 5,
"type_info": "Text"
},
{
"name": "theme_dark",
"ordinal": 6,
"type_info": "Text"
},
{
"name": "theme_light",
"ordinal": 7,
"type_info": "Text"
},
{
"name": "update_channel",
"ordinal": 8,
"type_info": "Text"
},
{
"name": "interface_font_size",
"ordinal": 9,
"type_info": "Int64"
},
{
"name": "interface_scale",
"ordinal": 10,
"type_info": "Int64"
},
{
"name": "editor_font_size",
"ordinal": 11,
"type_info": "Int64"
},
{
"name": "editor_soft_wrap",
"ordinal": 12,
"type_info": "Bool"
}
],
"parameters": {
"Right": 0
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false
]
},
"hash": "ca3485d87b060cd77c4114d2af544adf18f6f15341d9d5db40865e92a80da4e2"
}

View File

@@ -1,12 +0,0 @@
{
"db_name": "SQLite",
"query": "\n UPDATE settings SET (\n theme, appearance, theme_dark, theme_light, update_channel,\n interface_font_size, interface_scale, editor_font_size, editor_soft_wrap\n ) = (?, ?, ?, ?, ?, ?, ?, ?, ?) WHERE id = 'default';\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 9
},
"nullable": []
},
"hash": "efd8ba41ea909b18dd520c57c1d464c5ae057b720cbbedcaec1513d43535632c"
}

1918
src-tauri/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,12 +3,16 @@ workspace = { members = ["grpc"] }
[package]
name = "yaak-app"
version = "0.0.0"
description = "A network protocol testing utility app"
authors = ["Gregory Schier"]
license = "MIT"
repository = "https://github.com/gschier/yaak-app"
edition = "2021"
# Produce a library for mobile support
[lib]
name = "tauri_app_lib"
crate-type = ["staticlib", "cdylib", "lib"]
crate-type = ["staticlib", "cdylib", "rlib"]
[profile.release]
strip = true # Automatically strip symbols from the binary.
@@ -28,28 +32,32 @@ base64 = "0.22.0"
boa_engine = { version = "0.18.0", features = ["annex-b"] }
boa_runtime = { version = "0.18.0" }
chrono = { version = "0.4.31", features = ["serde"] }
http = "0.2.10"
futures = "0.3.26"
http = "0.2.8"
rand = "0.8.5"
reqwest = { version = "0.11.23", features = ["multipart", "cookies", "gzip", "brotli", "deflate", "json"] }
serde = { version = "1.0.198", features = ["derive"] }
serde_json = { version = "1.0.116", features = ["raw_value"] }
reqwest = { version = "0.11.23", features = ["multipart", "cookies", "gzip", "brotli", "deflate"] }
cookie = { version = "0.18.0" }
serde = { version = "1.0.195", features = ["derive"] }
serde_json = { version = "1.0.111", features = ["raw_value"] }
sqlx = { version = "0.7.4", features = ["sqlite", "runtime-tokio-rustls", "json", "chrono", "time"] }
tauri = { version = "2.0.0-beta", features = ["config-toml", "devtools", "protocol-asset"] }
tauri-plugin-clipboard-manager = "2.1.0-beta"
tauri-plugin-dialog = "2.0.0-beta"
tauri-plugin-log = { version = "2.0.0-beta", features = ["colored"] }
tauri-plugin-shell = "2.0.0-beta"
tauri-plugin-os = "2.0.0-beta"
tauri-plugin-updater = "2.0.0-beta"
tauri-plugin-window-state = "2.0.0-beta"
tauri-plugin-fs = "2.0.0-beta"
tauri-plugin-deep-link = "2.0.0-beta"
tauri = { version = "2.0.0-beta.17", features = [
"config-toml",
"devtools",
] }
tauri-plugin-clipboard-manager = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
tauri-plugin-dialog = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
tauri-plugin-log = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2", features = ["colored"] }
tauri-plugin-shell = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
tauri-plugin-os = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
tauri-plugin-updater = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
tauri-plugin-window-state = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
tauri-plugin-fs = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
tokio = { version = "1.36.0", features = ["sync"] }
uuid = "1.7.0"
log = "0.4.21"
uuid = "1.3.0"
log = "0.4.20"
datetime = "0.5.2"
window-shadows = "0.2.2"
reqwest_cookie_store = "0.6.0"
grpc = { path = "./grpc" }
tokio-stream = "0.1.15"
regex = "1.10.2"
hex_color = "3.0.0"

View File

@@ -39,18 +39,14 @@
}
]
},
"webview:allow-set-webview-zoom",
"window:allow-close",
"window:allow-is-fullscreen",
"window:allow-maximize",
"window:allow-minimize",
"window:allow-toggle-maximize",
"window:allow-set-decorations",
"window:allow-set-title",
"window:allow-start-dragging",
"window:allow-unmaximize",
"window:allow-theme",
"clipboard-manager:allow-read-text",
"clipboard-manager:allow-write-text"
"clipboard-manager:default"
]
}

3
src-tauri/gen/apple/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
xcuserdata/
build/
Externals/

Binary file not shown.

After

Width:  |  Height:  |  Size: 844 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -0,0 +1,116 @@
{
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "AppIcon-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "AppIcon-20x20@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "AppIcon-29x29@2x-1.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "AppIcon-29x29@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "AppIcon-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "AppIcon-40x40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "AppIcon-60x60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "AppIcon-60x60@3x.png",
"scale" : "3x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "AppIcon-20x20@1x.png",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "AppIcon-20x20@2x-1.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "AppIcon-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "AppIcon-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "AppIcon-40x40@1x.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "AppIcon-40x40@2x-1.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "AppIcon-76x76@1x.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "AppIcon-76x76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "AppIcon-83.5x83.5@2x.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "AppIcon-512@2x.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key>
<string>development</string>
</dict>
</plist>

View File

@@ -0,0 +1,21 @@
# Uncomment the next line to define a global platform for your project
target 'yaak-app_iOS' do
platform :ios, '13.0'
# Pods for yaak-app_iOS
end
target 'yaak-app_macOS' do
platform :osx, '11.0'
# Pods for yaak-app_macOS
end
# Delete the deployment target for iOS and macOS, causing it to be inherited from the Podfile
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
config.build_settings.delete 'MACOSX_DEPLOYMENT_TARGET'
end
end
end

View File

@@ -0,0 +1,8 @@
#pragma once
namespace ffi {
extern "C" {
void start_app();
}
}

View File

@@ -0,0 +1,6 @@
#include "bindings/bindings.h"
int main(int argc, char * argv[]) {
ffi::start_app();
return 0;
}

View File

@@ -0,0 +1,90 @@
name: yaak-app
options:
bundleIdPrefix: app.yaak
deploymentTarget:
iOS: 13.0
fileGroups: [../../src]
configs:
debug: debug
release: release
settingGroups:
app:
base:
PRODUCT_NAME: Yaak
PRODUCT_BUNDLE_IDENTIFIER: app.yaak.yaak-app
DEVELOPMENT_TEAM: 7PU3P6ELJ8
targetTemplates:
app:
type: application
sources:
- path: Sources
scheme:
environmentVariables:
RUST_BACKTRACE: full
RUST_LOG: info
settings:
groups: [app]
targets:
yaak-app_iOS:
type: application
platform: iOS
sources:
- path: Sources
- path: Assets.xcassets
- path: Externals
- path: yaak-app_iOS
- path: assets
buildPhase: resources
type: folder
info:
path: yaak-app_iOS/Info.plist
properties:
LSRequiresIPhoneOS: true
UILaunchStoryboardName: LaunchScreen
UIRequiredDeviceCapabilities: [arm64, metal]
UISupportedInterfaceOrientations:
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
UISupportedInterfaceOrientations~ipad:
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationPortraitUpsideDown
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
CFBundleShortVersionString: 2024.3.10
CFBundleVersion: 2024.3.10
entitlements:
path: yaak-app_iOS/yaak-app_iOS.entitlements
scheme:
environmentVariables:
RUST_BACKTRACE: full
RUST_LOG: info
settings:
base:
ENABLE_BITCODE: false
ARCHS: [arm64, arm64-sim]
VALID_ARCHS: arm64 arm64-sim
LIBRARY_SEARCH_PATHS[arch=x86_64]: $(inherited) $(PROJECT_DIR)/Externals/x86_64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)
LIBRARY_SEARCH_PATHS[arch=arm64]: $(inherited) $(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)
LIBRARY_SEARCH_PATHS[arch=arm64-sim]: $(inherited) $(PROJECT_DIR)/Externals/arm64-sim/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES: true
EXCLUDED_ARCHS[sdk=iphonesimulator*]: arm64
EXCLUDED_ARCHS[sdk=iphoneos*]: arm64-sim x86_64
groups: [app]
dependencies:
- framework: libapp_lib.a
embed: false
- sdk: CoreGraphics.framework
- sdk: Metal.framework
- sdk: MetalKit.framework
- sdk: QuartzCore.framework
- sdk: Security.framework
- sdk: UIKit.framework
- sdk: WebKit.framework
preBuildScripts:
- script: node tauri ios xcode-script -v --platform ${PLATFORM_DISPLAY_NAME:?} --sdk-root ${SDKROOT:?} --framework-search-paths "${FRAMEWORK_SEARCH_PATHS:?}" --header-search-paths "${HEADER_SEARCH_PATHS:?}" --gcc-preprocessor-definitions "${GCC_PREPROCESSOR_DEFINITIONS:-}" --configuration ${CONFIGURATION:?} ${FORCE_COLOR} ${ARCHS:?}
name: Build Rust Code
basedOnDependencyAnalysis: false
outputFiles:
- $(SRCROOT)/target/aarch64-apple-ios/${CONFIGURATION}/deps/libapp_lib.a
- $(SRCROOT)/target/x86_64-apple-ios/${CONFIGURATION}/deps/libapp_lib.a

View File

@@ -0,0 +1,481 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
0AC23E163631EF3775908406 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EDEF0D2E01608E7F464F71B6 /* WebKit.framework */; };
1B1BFDF8BC345D0D980E4427 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EF0B8CF73BE8166011E2CEAB /* QuartzCore.framework */; };
36588BE1A75B386BB2FEDAC5 /* MetalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A93A95F6B2F31FA92AA099E0 /* MetalKit.framework */; };
38E2C1B0E9FCC9A5FDE8876D /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF2908761467DF191C2A8939 /* Metal.framework */; };
8D518C1A67069BD7D339D055 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F34A96C5084EFDF1802A634 /* CoreGraphics.framework */; };
8DF67739DC49E577EB0FAE3F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 396F45DCFBE2C71866817528 /* Assets.xcassets */; };
A1D932F0E7399066AD07DC6D /* libapp_lib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 75D938BE0FA8770BA965AE1E /* libapp_lib.a */; };
AF0EEC868306E1D1C85994D0 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B5BF2E39256494269E65F8E /* Security.framework */; };
BE9FFDF51EB7DEBF707BB39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5415A3F2D217A47DD3BA40B3 /* UIKit.framework */; };
F0627C04787F4E187EF416F4 /* assets in Resources */ = {isa = PBXBuildFile; fileRef = 2A615609009B3AE2728043E4 /* assets */; };
FEE5934F5FFB0FBE10883AF2 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = C754460F1DAF2D414038A7EA /* main.mm */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
106BE62BE01A35403424018C /* main.rs */ = {isa = PBXFileReference; path = main.rs; sourceTree = "<group>"; };
14F240DAC31C5C52D7B4BB96 /* window_ext.rs */ = {isa = PBXFileReference; path = window_ext.rs; sourceTree = "<group>"; };
1B5226A88D8B805E878524C8 /* updates.rs */ = {isa = PBXFileReference; path = updates.rs; sourceTree = "<group>"; };
1F34A96C5084EFDF1802A634 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
1F5A647F82A24722F3C830BB /* plugin.rs */ = {isa = PBXFileReference; path = plugin.rs; sourceTree = "<group>"; };
2A615609009B3AE2728043E4 /* assets */ = {isa = PBXFileReference; lastKnownFileType = folder; path = assets; sourceTree = SOURCE_ROOT; };
396F45DCFBE2C71866817528 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
53872C1120171EDC4A6DFEDD /* analytics.rs */ = {isa = PBXFileReference; path = analytics.rs; sourceTree = "<group>"; };
5415A3F2D217A47DD3BA40B3 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
5C1B6610F62B56E1947BEBBD /* http.rs */ = {isa = PBXFileReference; path = http.rs; sourceTree = "<group>"; };
6286C385ABAD2E04237679D7 /* yaak-app_iOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "yaak-app_iOS.entitlements"; sourceTree = "<group>"; };
75D938BE0FA8770BA965AE1E /* libapp_lib.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libapp_lib.a; sourceTree = "<group>"; };
7B5BF2E39256494269E65F8E /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
A2CC02313D71CECB68031D53 /* grpc.rs */ = {isa = PBXFileReference; path = grpc.rs; sourceTree = "<group>"; };
A6DA9B210723CA84891876F8 /* bindings.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = bindings.h; sourceTree = "<group>"; };
A93A95F6B2F31FA92AA099E0 /* MetalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalKit.framework; path = System/Library/Frameworks/MetalKit.framework; sourceTree = SDKROOT; };
C754460F1DAF2D414038A7EA /* main.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = "<group>"; };
D69BFB768591FDEEF65198EE /* yaak-app_iOS.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = "yaak-app_iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
DDDE197D9C6BC5680EEEEA00 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
DF2908761467DF191C2A8939 /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; };
DF45D08D97DE587CABF9537E /* window_menu.rs */ = {isa = PBXFileReference; path = window_menu.rs; sourceTree = "<group>"; };
E1E84E267D81D6437901B1C6 /* render.rs */ = {isa = PBXFileReference; path = render.rs; sourceTree = "<group>"; };
E964D3637BAED49E34B91739 /* models.rs */ = {isa = PBXFileReference; path = models.rs; sourceTree = "<group>"; };
EDEF0D2E01608E7F464F71B6 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
EF0B8CF73BE8166011E2CEAB /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
FB34CB48BB9F25D49F80D513 /* lib.rs */ = {isa = PBXFileReference; path = lib.rs; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
D8E8888B0F3E4411B98AE8EE /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
A1D932F0E7399066AD07DC6D /* libapp_lib.a in Frameworks */,
8D518C1A67069BD7D339D055 /* CoreGraphics.framework in Frameworks */,
38E2C1B0E9FCC9A5FDE8876D /* Metal.framework in Frameworks */,
36588BE1A75B386BB2FEDAC5 /* MetalKit.framework in Frameworks */,
1B1BFDF8BC345D0D980E4427 /* QuartzCore.framework in Frameworks */,
AF0EEC868306E1D1C85994D0 /* Security.framework in Frameworks */,
BE9FFDF51EB7DEBF707BB39A /* UIKit.framework in Frameworks */,
0AC23E163631EF3775908406 /* WebKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
0844ACEFE550685042AC6029 /* Products */ = {
isa = PBXGroup;
children = (
D69BFB768591FDEEF65198EE /* yaak-app_iOS.app */,
);
name = Products;
sourceTree = "<group>";
};
6D0B6FF641B88DAF74C78B00 /* Externals */ = {
isa = PBXGroup;
children = (
);
path = Externals;
sourceTree = "<group>";
};
8A07575CB8654BB9107F9A32 /* bindings */ = {
isa = PBXGroup;
children = (
A6DA9B210723CA84891876F8 /* bindings.h */,
);
path = bindings;
sourceTree = "<group>";
};
8F0B46911FBEF2B246BE3385 /* yaak-app */ = {
isa = PBXGroup;
children = (
C754460F1DAF2D414038A7EA /* main.mm */,
8A07575CB8654BB9107F9A32 /* bindings */,
);
path = "yaak-app";
sourceTree = "<group>";
};
90E982C0E9B45CBAAE66E16D /* Frameworks */ = {
isa = PBXGroup;
children = (
1F34A96C5084EFDF1802A634 /* CoreGraphics.framework */,
75D938BE0FA8770BA965AE1E /* libapp_lib.a */,
DF2908761467DF191C2A8939 /* Metal.framework */,
A93A95F6B2F31FA92AA099E0 /* MetalKit.framework */,
EF0B8CF73BE8166011E2CEAB /* QuartzCore.framework */,
7B5BF2E39256494269E65F8E /* Security.framework */,
5415A3F2D217A47DD3BA40B3 /* UIKit.framework */,
EDEF0D2E01608E7F464F71B6 /* WebKit.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
C88F9D29DC52F052255C35A3 = {
isa = PBXGroup;
children = (
2A615609009B3AE2728043E4 /* assets */,
396F45DCFBE2C71866817528 /* Assets.xcassets */,
6D0B6FF641B88DAF74C78B00 /* Externals */,
EBC83899FBFA4A3D0A92837F /* Sources */,
F3A6B45E25E23922AB1BDB34 /* src */,
D49CF68C9105CE84E2084C14 /* yaak-app_iOS */,
90E982C0E9B45CBAAE66E16D /* Frameworks */,
0844ACEFE550685042AC6029 /* Products */,
);
sourceTree = "<group>";
};
D49CF68C9105CE84E2084C14 /* yaak-app_iOS */ = {
isa = PBXGroup;
children = (
DDDE197D9C6BC5680EEEEA00 /* Info.plist */,
6286C385ABAD2E04237679D7 /* yaak-app_iOS.entitlements */,
);
path = "yaak-app_iOS";
sourceTree = "<group>";
};
EBC83899FBFA4A3D0A92837F /* Sources */ = {
isa = PBXGroup;
children = (
8F0B46911FBEF2B246BE3385 /* yaak-app */,
);
path = Sources;
sourceTree = "<group>";
};
F3A6B45E25E23922AB1BDB34 /* src */ = {
isa = PBXGroup;
children = (
53872C1120171EDC4A6DFEDD /* analytics.rs */,
A2CC02313D71CECB68031D53 /* grpc.rs */,
5C1B6610F62B56E1947BEBBD /* http.rs */,
FB34CB48BB9F25D49F80D513 /* lib.rs */,
106BE62BE01A35403424018C /* main.rs */,
E964D3637BAED49E34B91739 /* models.rs */,
1F5A647F82A24722F3C830BB /* plugin.rs */,
E1E84E267D81D6437901B1C6 /* render.rs */,
1B5226A88D8B805E878524C8 /* updates.rs */,
14F240DAC31C5C52D7B4BB96 /* window_ext.rs */,
DF45D08D97DE587CABF9537E /* window_menu.rs */,
);
name = src;
path = ../../src;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
7C3E2AC18A0A227C2DF356E2 /* yaak-app_iOS */ = {
isa = PBXNativeTarget;
buildConfigurationList = C05E07AE7C7B25CACFADCDD4 /* Build configuration list for PBXNativeTarget "yaak-app_iOS" */;
buildPhases = (
5454ED506FC51D41C81A0318 /* Build Rust Code */,
C3495A2849227C6276D3876E /* Sources */,
E148188313FB67F061AB4E59 /* Resources */,
D8E8888B0F3E4411B98AE8EE /* Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = "yaak-app_iOS";
productName = "yaak-app_iOS";
productReference = D69BFB768591FDEEF65198EE /* yaak-app_iOS.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
A8F6206BC76F061F1FEFD439 /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
LastUpgradeCheck = 1430;
TargetAttributes = {
7C3E2AC18A0A227C2DF356E2 = {
DevelopmentTeam = 7PU3P6ELJ8;
};
};
};
buildConfigurationList = 24EF8D1B948FFF6B275FB0F4 /* Build configuration list for PBXProject "yaak-app" */;
compatibilityVersion = "Xcode 14.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
Base,
en,
);
mainGroup = C88F9D29DC52F052255C35A3;
projectDirPath = "";
projectRoot = "";
targets = (
7C3E2AC18A0A227C2DF356E2 /* yaak-app_iOS */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
E148188313FB67F061AB4E59 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8DF67739DC49E577EB0FAE3F /* Assets.xcassets in Resources */,
F0627C04787F4E187EF416F4 /* assets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
5454ED506FC51D41C81A0318 /* Build Rust Code */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
name = "Build Rust Code";
outputFileListPaths = (
);
outputPaths = (
"$(SRCROOT)/target/aarch64-apple-ios/${CONFIGURATION}/deps/libapp_lib.a",
"$(SRCROOT)/target/x86_64-apple-ios/${CONFIGURATION}/deps/libapp_lib.a",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "node tauri ios xcode-script -v --platform ${PLATFORM_DISPLAY_NAME:?} --sdk-root ${SDKROOT:?} --framework-search-paths \"${FRAMEWORK_SEARCH_PATHS:?}\" --header-search-paths \"${HEADER_SEARCH_PATHS:?}\" --gcc-preprocessor-definitions \"${GCC_PREPROCESSOR_DEFINITIONS:-}\" --configuration ${CONFIGURATION:?} ${FORCE_COLOR} ${ARCHS:?}";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
C3495A2849227C6276D3876E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
FEE5934F5FFB0FBE10883AF2 /* main.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
35D1DB294FFD067C835186C7 /* debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
"DEBUG=1",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
};
name = debug;
};
368BB1E364597E7675463634 /* release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ARCHS = (
arm64,
"arm64-sim",
);
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = "yaak-app_iOS/yaak-app_iOS.entitlements";
CODE_SIGN_IDENTITY = "iPhone Developer";
DEVELOPMENT_TEAM = 7PU3P6ELJ8;
ENABLE_BITCODE = NO;
"EXCLUDED_ARCHS[sdk=iphoneos*]" = "arm64-sim x86_64";
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\".\"",
);
INFOPLIST_FILE = "yaak-app_iOS/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
"LIBRARY_SEARCH_PATHS[arch=arm64-sim]" = "$(inherited) $(PROJECT_DIR)/Externals/arm64-sim/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)";
"LIBRARY_SEARCH_PATHS[arch=arm64]" = "$(inherited) $(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)";
"LIBRARY_SEARCH_PATHS[arch=x86_64]" = "$(inherited) $(PROJECT_DIR)/Externals/x86_64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)";
PRODUCT_BUNDLE_IDENTIFIER = "app.yaak.yaak-app";
PRODUCT_NAME = Yaak;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALID_ARCHS = "arm64 arm64-sim";
};
name = release;
};
45382E89556BF93E8D1F1C2D /* debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ARCHS = (
arm64,
"arm64-sim",
);
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = "yaak-app_iOS/yaak-app_iOS.entitlements";
CODE_SIGN_IDENTITY = "iPhone Developer";
DEVELOPMENT_TEAM = 7PU3P6ELJ8;
ENABLE_BITCODE = NO;
"EXCLUDED_ARCHS[sdk=iphoneos*]" = "arm64-sim x86_64";
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\".\"",
);
INFOPLIST_FILE = "yaak-app_iOS/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
"LIBRARY_SEARCH_PATHS[arch=arm64-sim]" = "$(inherited) $(PROJECT_DIR)/Externals/arm64-sim/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)";
"LIBRARY_SEARCH_PATHS[arch=arm64]" = "$(inherited) $(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)";
"LIBRARY_SEARCH_PATHS[arch=x86_64]" = "$(inherited) $(PROJECT_DIR)/Externals/x86_64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)";
PRODUCT_BUNDLE_IDENTIFIER = "app.yaak.yaak-app";
PRODUCT_NAME = Yaak;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALID_ARCHS = "arm64 arm64-sim";
};
name = debug;
};
ABD0A3DD3D5C66C839496F44 /* release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 5.0;
};
name = release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
24EF8D1B948FFF6B275FB0F4 /* Build configuration list for PBXProject "yaak-app" */ = {
isa = XCConfigurationList;
buildConfigurations = (
35D1DB294FFD067C835186C7 /* debug */,
ABD0A3DD3D5C66C839496F44 /* release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = debug;
};
C05E07AE7C7B25CACFADCDD4 /* Build configuration list for PBXNativeTarget "yaak-app_iOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
45382E89556BF93E8D1F1C2D /* debug */,
368BB1E364597E7675463634 /* release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = debug;
};
/* End XCConfigurationList section */
};
rootObject = A8F6206BC76F061F1FEFD439 /* Project object */;
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildSystemType</key>
<string>Original</string>
<key>DisableBuildSystemDeprecationDiagnostic</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1430"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7C3E2AC18A0A227C2DF356E2"
BuildableName = "Yaak.app"
BlueprintName = "yaak-app_iOS"
ReferencedContainer = "container:yaak-app.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "NO">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7C3E2AC18A0A227C2DF356E2"
BuildableName = "Yaak.app"
BlueprintName = "yaak-app_iOS"
ReferencedContainer = "container:yaak-app.xcodeproj">
</BuildableReference>
</MacroExpansion>
<EnvironmentVariables>
<EnvironmentVariable
key = "RUST_BACKTRACE"
value = "full"
isEnabled = "YES">
</EnvironmentVariable>
<EnvironmentVariable
key = "RUST_LOG"
value = "info"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7C3E2AC18A0A227C2DF356E2"
BuildableName = "Yaak.app"
BlueprintName = "yaak-app_iOS"
ReferencedContainer = "container:yaak-app.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<EnvironmentVariables>
<EnvironmentVariable
key = "RUST_BACKTRACE"
value = "full"
isEnabled = "YES">
</EnvironmentVariable>
<EnvironmentVariable
key = "RUST_LOG"
value = "info"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
</LaunchAction>
<ProfileAction
buildConfiguration = "release"
shouldUseLaunchSchemeArgsEnv = "NO"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7C3E2AC18A0A227C2DF356E2"
BuildableName = "Yaak.app"
BlueprintName = "yaak-app_iOS"
ReferencedContainer = "container:yaak-app.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<EnvironmentVariables>
<EnvironmentVariable
key = "RUST_BACKTRACE"
value = "full"
isEnabled = "YES">
</EnvironmentVariable>
<EnvironmentVariable
key = "RUST_LOG"
value = "info"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>2024.3.10</string>
<key>CFBundleVersion</key>
<string>2024.3.10</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>arm64</string>
<string>metal</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
</plist>

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
{"main":{"identifier":"main","description":"Main permissions","local":true,"windows":["*"],"permissions":["os:allow-os-type","event:allow-emit","clipboard-manager:allow-write-text","clipboard-manager:allow-read-text","dialog:allow-open","dialog:allow-save","event:allow-listen","event:allow-unlisten","fs:allow-read-file","fs:allow-read-text-file",{"identifier":"fs:scope","allow":[{"path":"$APPDATA"},{"path":"$APPDATA/**"}]},"shell:allow-open",{"identifier":"shell:allow-execute","allow":[{"args":true,"name":"protoc","sidecar":true}]},"webview:allow-set-webview-zoom","window:allow-close","window:allow-is-fullscreen","window:allow-maximize","window:allow-minimize","window:allow-toggle-maximize","window:allow-set-decorations","window:allow-set-title","window:allow-start-dragging","window:allow-unmaximize","window:allow-theme","clipboard-manager:allow-read-text","clipboard-manager:allow-write-text"]}}
{"main":{"identifier":"main","description":"Main permissions","local":true,"windows":["*"],"permissions":["os:allow-os-type","event:allow-emit","clipboard-manager:allow-write-text","clipboard-manager:allow-read-text","dialog:allow-open","dialog:allow-save","event:allow-listen","event:allow-unlisten","fs:allow-read-file","fs:allow-read-text-file",{"identifier":"fs:scope","allow":[{"path":"$APPDATA"},{"path":"$APPDATA/**"}]},"shell:allow-open",{"identifier":"shell:allow-execute","allow":[{"args":true,"name":"protoc","sidecar":true}]},"window:allow-close","window:allow-is-fullscreen","window:allow-maximize","window:allow-minimize","window:allow-set-decorations","window:allow-set-title","window:allow-start-dragging","window:allow-unmaximize","clipboard-manager:default"]}}

View File

@@ -2216,13 +2216,6 @@
"shell:allow-open"
]
},
{
"description": "shell:allow-spawn -> Enables the spawn command without any pre-configured scope.",
"type": "string",
"enum": [
"shell:allow-spawn"
]
},
{
"description": "shell:allow-stdin-write -> Enables the stdin_write command without any pre-configured scope.",
"type": "string",
@@ -2251,13 +2244,6 @@
"shell:deny-open"
]
},
{
"description": "shell:deny-spawn -> Denies the spawn command without any pre-configured scope.",
"type": "string",
"enum": [
"shell:deny-spawn"
]
},
{
"description": "shell:deny-stdin-write -> Denies the stdin_write command without any pre-configured scope.",
"type": "string",
@@ -2512,69 +2498,6 @@
"clipboard-manager:deny-write-text"
]
},
{
"description": "deep-link:default -> Allows reading the opened deep link via the get_current command",
"type": "string",
"enum": [
"deep-link:default"
]
},
{
"description": "deep-link:allow-get-current -> Enables the get_current command without any pre-configured scope.",
"type": "string",
"enum": [
"deep-link:allow-get-current"
]
},
{
"description": "deep-link:allow-is-registered -> Enables the is_registered command without any pre-configured scope.",
"type": "string",
"enum": [
"deep-link:allow-is-registered"
]
},
{
"description": "deep-link:allow-register -> Enables the register command without any pre-configured scope.",
"type": "string",
"enum": [
"deep-link:allow-register"
]
},
{
"description": "deep-link:allow-unregister -> Enables the unregister command without any pre-configured scope.",
"type": "string",
"enum": [
"deep-link:allow-unregister"
]
},
{
"description": "deep-link:deny-get-current -> Denies the get_current command without any pre-configured scope.",
"type": "string",
"enum": [
"deep-link:deny-get-current"
]
},
{
"description": "deep-link:deny-is-registered -> Denies the is_registered command without any pre-configured scope.",
"type": "string",
"enum": [
"deep-link:deny-is-registered"
]
},
{
"description": "deep-link:deny-register -> Denies the register command without any pre-configured scope.",
"type": "string",
"enum": [
"deep-link:deny-register"
]
},
{
"description": "deep-link:deny-unregister -> Denies the unregister command without any pre-configured scope.",
"type": "string",
"enum": [
"deep-link:deny-unregister"
]
},
{
"type": "string",
"enum": [
@@ -5400,13 +5323,6 @@
"shell:allow-open"
]
},
{
"description": "shell:allow-spawn -> Enables the spawn command without any pre-configured scope.",
"type": "string",
"enum": [
"shell:allow-spawn"
]
},
{
"description": "shell:allow-stdin-write -> Enables the stdin_write command without any pre-configured scope.",
"type": "string",
@@ -5435,13 +5351,6 @@
"shell:deny-open"
]
},
{
"description": "shell:deny-spawn -> Denies the spawn command without any pre-configured scope.",
"type": "string",
"enum": [
"shell:deny-spawn"
]
},
{
"description": "shell:deny-stdin-write -> Denies the stdin_write command without any pre-configured scope.",
"type": "string",
@@ -5624,13 +5533,6 @@
"updater:allow-check"
]
},
{
"description": "updater:allow-download -> Enables the download command without any pre-configured scope.",
"type": "string",
"enum": [
"updater:allow-download"
]
},
{
"description": "updater:allow-download-and-install -> Enables the download_and_install command without any pre-configured scope.",
"type": "string",
@@ -5638,13 +5540,6 @@
"updater:allow-download-and-install"
]
},
{
"description": "updater:allow-install -> Enables the install command without any pre-configured scope.",
"type": "string",
"enum": [
"updater:allow-install"
]
},
{
"description": "updater:deny-check -> Denies the check command without any pre-configured scope.",
"type": "string",
@@ -5652,13 +5547,6 @@
"updater:deny-check"
]
},
{
"description": "updater:deny-download -> Denies the download command without any pre-configured scope.",
"type": "string",
"enum": [
"updater:deny-download"
]
},
{
"description": "updater:deny-download-and-install -> Denies the download_and_install command without any pre-configured scope.",
"type": "string",
@@ -5666,13 +5554,6 @@
"updater:deny-download-and-install"
]
},
{
"description": "updater:deny-install -> Denies the install command without any pre-configured scope.",
"type": "string",
"enum": [
"updater:deny-install"
]
},
{
"description": "webview:default -> Default permissions for the plugin.",
"type": "string",
@@ -6016,13 +5897,6 @@
"window:allow-minimize"
]
},
{
"description": "window:allow-monitor-from-point -> Enables the monitor_from_point command without any pre-configured scope.",
"type": "string",
"enum": [
"window:allow-monitor-from-point"
]
},
{
"description": "window:allow-outer-position -> Enables the outer_position command without any pre-configured scope.",
"type": "string",
@@ -6457,13 +6331,6 @@
"window:deny-minimize"
]
},
{
"description": "window:deny-monitor-from-point -> Denies the monitor_from_point command without any pre-configured scope.",
"type": "string",
"enum": [
"window:deny-monitor-from-point"
]
},
{
"description": "window:deny-outer-position -> Denies the outer_position command without any pre-configured scope.",
"type": "string",

File diff suppressed because it is too large Load Diff

View File

@@ -2216,13 +2216,6 @@
"shell:allow-open"
]
},
{
"description": "shell:allow-spawn -> Enables the spawn command without any pre-configured scope.",
"type": "string",
"enum": [
"shell:allow-spawn"
]
},
{
"description": "shell:allow-stdin-write -> Enables the stdin_write command without any pre-configured scope.",
"type": "string",
@@ -2251,13 +2244,6 @@
"shell:deny-open"
]
},
{
"description": "shell:deny-spawn -> Denies the spawn command without any pre-configured scope.",
"type": "string",
"enum": [
"shell:deny-spawn"
]
},
{
"description": "shell:deny-stdin-write -> Denies the stdin_write command without any pre-configured scope.",
"type": "string",
@@ -2512,69 +2498,6 @@
"clipboard-manager:deny-write-text"
]
},
{
"description": "deep-link:default -> Allows reading the opened deep link via the get_current command",
"type": "string",
"enum": [
"deep-link:default"
]
},
{
"description": "deep-link:allow-get-current -> Enables the get_current command without any pre-configured scope.",
"type": "string",
"enum": [
"deep-link:allow-get-current"
]
},
{
"description": "deep-link:allow-is-registered -> Enables the is_registered command without any pre-configured scope.",
"type": "string",
"enum": [
"deep-link:allow-is-registered"
]
},
{
"description": "deep-link:allow-register -> Enables the register command without any pre-configured scope.",
"type": "string",
"enum": [
"deep-link:allow-register"
]
},
{
"description": "deep-link:allow-unregister -> Enables the unregister command without any pre-configured scope.",
"type": "string",
"enum": [
"deep-link:allow-unregister"
]
},
{
"description": "deep-link:deny-get-current -> Denies the get_current command without any pre-configured scope.",
"type": "string",
"enum": [
"deep-link:deny-get-current"
]
},
{
"description": "deep-link:deny-is-registered -> Denies the is_registered command without any pre-configured scope.",
"type": "string",
"enum": [
"deep-link:deny-is-registered"
]
},
{
"description": "deep-link:deny-register -> Denies the register command without any pre-configured scope.",
"type": "string",
"enum": [
"deep-link:deny-register"
]
},
{
"description": "deep-link:deny-unregister -> Denies the unregister command without any pre-configured scope.",
"type": "string",
"enum": [
"deep-link:deny-unregister"
]
},
{
"type": "string",
"enum": [
@@ -5400,13 +5323,6 @@
"shell:allow-open"
]
},
{
"description": "shell:allow-spawn -> Enables the spawn command without any pre-configured scope.",
"type": "string",
"enum": [
"shell:allow-spawn"
]
},
{
"description": "shell:allow-stdin-write -> Enables the stdin_write command without any pre-configured scope.",
"type": "string",
@@ -5435,13 +5351,6 @@
"shell:deny-open"
]
},
{
"description": "shell:deny-spawn -> Denies the spawn command without any pre-configured scope.",
"type": "string",
"enum": [
"shell:deny-spawn"
]
},
{
"description": "shell:deny-stdin-write -> Denies the stdin_write command without any pre-configured scope.",
"type": "string",
@@ -5624,13 +5533,6 @@
"updater:allow-check"
]
},
{
"description": "updater:allow-download -> Enables the download command without any pre-configured scope.",
"type": "string",
"enum": [
"updater:allow-download"
]
},
{
"description": "updater:allow-download-and-install -> Enables the download_and_install command without any pre-configured scope.",
"type": "string",
@@ -5638,13 +5540,6 @@
"updater:allow-download-and-install"
]
},
{
"description": "updater:allow-install -> Enables the install command without any pre-configured scope.",
"type": "string",
"enum": [
"updater:allow-install"
]
},
{
"description": "updater:deny-check -> Denies the check command without any pre-configured scope.",
"type": "string",
@@ -5652,13 +5547,6 @@
"updater:deny-check"
]
},
{
"description": "updater:deny-download -> Denies the download command without any pre-configured scope.",
"type": "string",
"enum": [
"updater:deny-download"
]
},
{
"description": "updater:deny-download-and-install -> Denies the download_and_install command without any pre-configured scope.",
"type": "string",
@@ -5666,13 +5554,6 @@
"updater:deny-download-and-install"
]
},
{
"description": "updater:deny-install -> Denies the install command without any pre-configured scope.",
"type": "string",
"enum": [
"updater:deny-install"
]
},
{
"description": "webview:default -> Default permissions for the plugin.",
"type": "string",
@@ -6016,13 +5897,6 @@
"window:allow-minimize"
]
},
{
"description": "window:allow-monitor-from-point -> Enables the monitor_from_point command without any pre-configured scope.",
"type": "string",
"enum": [
"window:allow-monitor-from-point"
]
},
{
"description": "window:allow-outer-position -> Enables the outer_position command without any pre-configured scope.",
"type": "string",
@@ -6457,13 +6331,6 @@
"window:deny-minimize"
]
},
{
"description": "window:deny-monitor-from-point -> Denies the monitor_from_point command without any pre-configured scope.",
"type": "string",
"enum": [
"window:deny-monitor-from-point"
]
},
{
"description": "window:deny-outer-position -> Denies the outer_position command without any pre-configured scope.",
"type": "string",

File diff suppressed because it is too large Load Diff

View File

@@ -14,9 +14,11 @@ serde = { version = "1.0.196", features = ["derive"] }
serde_json = "1.0.113"
prost-reflect = { version = "0.12.0", features = ["serde", "derive"] }
log = "0.4.20"
once_cell = { version = "1.19.0", features = [] }
anyhow = "1.0.79"
hyper = { version = "0.14" }
hyper-rustls = { version = "0.24.0", features = ["http2"] }
protoc-bin-vendored = "3.0.0"
uuid = { version = "1.7.0", features = ["v4"] }
tauri = { version = "2.0.0-beta" }
tauri-plugin-shell = "2.0.0-beta"
tauri = { version = "2.0.0-beta.16" }
tauri-plugin-shell = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }

View File

@@ -1,4 +0,0 @@
ALTER TABLE settings
ADD COLUMN theme_dark TEXT DEFAULT 'yaak-dark' NOT NULL;
ALTER TABLE settings
ADD COLUMN theme_light TEXT DEFAULT 'yaak-light' NOT NULL;

View File

@@ -1,4 +0,0 @@
ALTER TABLE settings ADD COLUMN interface_font_size INTEGER DEFAULT 15 NOT NULL;
ALTER TABLE settings ADD COLUMN interface_scale INTEGER DEFAULT 1 NOT NULL;
ALTER TABLE settings ADD COLUMN editor_font_size INTEGER DEFAULT 13 NOT NULL;
ALTER TABLE settings ADD COLUMN editor_soft_wrap BOOLEAN DEFAULT 1 NOT NULL;

View File

@@ -9,10 +9,10 @@ var j = "(?:" + [
">\\&",
"<\\&",
"[&;()|<>]"
].join("|") + ")", D = new RegExp("^" + j + "$"), q = "|&;()<> \\t", M = '"((\\\\"|[^"])*?)"', Q = "'((\\\\'|[^'])*?)'", V = /^#$/, _ = "'", G = '"', U = "$", $ = "", z = 4294967296;
].join("|") + ")", D = new RegExp("^" + j + "$"), q = "|&;()<> \\t", M = '"((\\\\"|[^"])*?)"', Q = "'((\\\\'|[^'])*?)'", V = /^#$/, _ = "'", G = '"', U = "$", R = "", z = 4294967296;
for (var L = 0; L < 4; L++)
$ += (z * Math.random()).toString(16);
var J = new RegExp("^" + $);
R += (z * Math.random()).toString(16);
var J = new RegExp("^" + R);
function X(n, s) {
for (var e = s.lastIndex, t = [], c; c = s.exec(n); )
t.push(c), s.lastIndex === c.index && (s.lastIndex += 1);
@@ -20,7 +20,7 @@ function X(n, s) {
}
function F(n, s, e) {
var t = typeof n == "function" ? n(e) : n[e];
return typeof t > "u" && e != "" ? t = "" : typeof t > "u" && (t = "$"), typeof t == "object" ? s + $ + JSON.stringify(t) + $ : s + t;
return typeof t > "u" && e != "" ? t = "" : typeof t > "u" && (t = "$"), typeof t == "object" ? s + R + JSON.stringify(t) + R : s + t;
}
function K(n, s, e) {
e || (e = {});
@@ -39,30 +39,30 @@ function K(n, s, e) {
return;
if (D.test(a))
return { op: a };
var x = !1, C = !1, d = "", O = !1, i;
function T() {
var x = !1, O = !1, p = "", A = !1, i;
function b() {
i += 1;
var v, p, R = a.charAt(i);
if (R === "{") {
var v, d, T = a.charAt(i);
if (T === "{") {
if (i += 1, a.charAt(i) === "}")
throw new Error("Bad substitution: " + a.slice(i - 2, i + 1));
if (v = a.indexOf("}", i), v < 0)
throw new Error("Bad substitution: " + a.slice(i));
p = a.slice(i, v), i = v;
} else if (/[*@#?$!_-]/.test(R))
p = R, i += 1;
d = a.slice(i, v), i = v;
} else if (/[*@#?$!_-]/.test(T))
d = T, i += 1;
else {
var g = a.slice(i);
v = g.match(/[^\w\d_]/), v ? (p = g.slice(0, v.index), i += v.index - 1) : (p = g, i = a.length);
v = g.match(/[^\w\d_]/), v ? (d = g.slice(0, v.index), i += v.index - 1) : (d = g, i = a.length);
}
return F(s, "", p);
return F(s, "", d);
}
for (i = 0; i < a.length; i++) {
var u = a.charAt(i);
if (O = O || !x && (u === "*" || u === "?"), C)
d += u, C = !1;
if (A = A || !x && (u === "*" || u === "?"), O)
p += u, O = !1;
else if (x)
u === x ? x = !1 : x == _ ? d += u : u === t ? (i += 1, u = a.charAt(i), u === G || u === t || u === U ? d += u : d += t + u) : u === U ? d += T() : d += u;
u === x ? x = !1 : x == _ ? p += u : u === t ? (i += 1, u = a.charAt(i), u === G || u === t || u === U ? p += u : p += t + u) : u === U ? p += b() : p += u;
else if (u === G || u === _)
x = u;
else {
@@ -70,13 +70,13 @@ function K(n, s, e) {
return { op: a };
if (V.test(u)) {
w = !0;
var b = { comment: n.slice(r.index + i + 1) };
return d.length ? [d, b] : [b];
var E = { comment: n.slice(r.index + i + 1) };
return p.length ? [p, E] : [E];
} else
u === t ? C = !0 : u === U ? d += T() : d += u;
u === t ? O = !0 : u === U ? p += b() : p += u;
}
}
return O ? { op: "glob", pattern: d } : d;
return A ? { op: "glob", pattern: p } : p;
}).reduce(function(r, a) {
return typeof a > "u" ? r : r.concat(a);
}, []);
@@ -86,9 +86,9 @@ var Y = function(s, e, t) {
return typeof e != "function" ? c : c.reduce(function(m, f) {
if (typeof f == "object")
return m.concat(f);
var w = f.split(RegExp("(" + $ + ".*?" + $ + ")", "g"));
var w = f.split(RegExp("(" + R + ".*?" + R + ")", "g"));
return w.length === 1 ? m.concat(w[0]) : m.concat(w.filter(Boolean).map(function(r) {
return J.test(r) ? JSON.parse(r.split($)[1]) : r;
return J.test(r) ? JSON.parse(r.split(R)[1]) : r;
}));
}, []);
}, Z = Y;
@@ -118,7 +118,7 @@ const ae = "curl", se = "cURL", ie = "cURL command line tool", H = ["d", "data",
function oe(n) {
if (!n.match(/^\s*curl /))
return null;
const s = [], e = n.replace(/\ncurl/g, "; curl");
const s = [], e = n.replace(/([^\\])\n/g, "$1; ");
let t = [];
const m = Z(e).flatMap((r) => typeof r == "string" && r.startsWith("-") && !r.startsWith("--") && r.length > 2 ? [r.slice(0, 2), r.slice(2)] : r);
for (const r of m) {
@@ -158,84 +158,73 @@ function te(n, s) {
for (let o = 1; o < n.length; o++) {
let l = n[o];
if (typeof l == "string" && (l = l.trim()), typeof l == "string" && l.match(/^-{1,2}[\w-]+/)) {
const E = l[0] === "-" && l[1] !== "-";
const $ = l[0] === "-" && l[1] !== "-";
let h = l.replace(/^-{1,2}/, "");
if (!ee.includes(h))
continue;
let y;
const S = n[o + 1];
E && h.length > 1 ? (y = h.slice(1), h = h.slice(0, 1)) : typeof S == "string" && !S.startsWith("-") ? (y = S, o++) : y = !0, e[h] = e[h] || [], e[h].push(y);
$ && h.length > 1 ? (y = h.slice(1), h = h.slice(0, 1)) : typeof S == "string" && !S.startsWith("-") ? (y = S, o++) : y = !0, e[h] = e[h] || [], e[h].push(y);
} else
l && t.push(l);
}
let c, m;
const f = A(e, t[0] || "", ["url"]), [w, r] = W(f, "?");
const f = C(e, t[0] || "", ["url"]), [w, r] = W(f, "?");
c = (r == null ? void 0 : r.split("&").map((o) => {
const l = W(o, "=");
return { name: l[0] ?? "", value: l[1] ?? "", enabled: !0 };
return { name: l[0] ?? "", value: l[1] ?? "" };
})) ?? [], m = w ?? f;
const [a, x] = A(e, "", ["u", "user"]).split(/:(.*)$/), C = A(e, !1, ["digest"]), d = a ? C ? "digest" : "basic" : null, O = a ? {
const [a, x] = C(e, "", ["u", "user"]).split(/:(.*)$/), O = C(e, !1, ["digest"]), p = a ? O ? "digest" : "basic" : null, A = a ? {
username: a.trim(),
password: (x ?? "").trim()
} : {}, i = [
...e.header || [],
...e.H || []
].map((o) => {
const [l, E] = o.split(/:(.*)$/);
return E ? {
const [l, $] = o.split(/:(.*)$/);
return $ ? {
name: (l ?? "").trim(),
value: E.trim(),
enabled: !0
value: $.trim()
} : {
name: (l ?? "").trim().replace(/;$/, ""),
value: "",
enabled: !0
value: ""
};
}), T = [
}), b = [
...e.cookie || [],
...e.b || []
].map((o) => {
const l = o.split("=", 1)[0], E = o.replace(`${l}=`, "");
return `${l}=${E}`;
const l = o.split("=", 1)[0], $ = o.replace(`${l}=`, "");
return `${l}=${$}`;
}).join("; "), u = i.find((o) => o.name.toLowerCase() === "cookie");
T && u ? u.value += `; ${T}` : T && i.push({
b && u ? u.value += `; ${b}` : b && i.push({
name: "Cookie",
value: T,
enabled: !0
value: b
});
const b = ne(e), v = i.find((o) => o.name.toLowerCase() === "content-type"), p = v ? v.value.split(";")[0] : null, R = [
const E = ne(e), v = i.find((o) => o.name.toLowerCase() === "content-type"), d = v ? v.value.split(";")[0] : null, T = [
...e.form || [],
...e.F || []
].map((o) => {
const l = o.split("="), E = l[0] ?? "", h = l[1] ?? "", y = {
name: E,
const l = o.split("="), $ = l[0] ?? "", h = l[1] ?? "", y = {
name: $,
enabled: !0
};
return h.indexOf("@") === 0 ? y.file = h.slice(1) : y.value = h, y;
});
let g = {}, I = null;
const B = A(e, !1, ["G", "get"]);
b.length > 0 && B ? c.push(...b) : b.length > 0 && (p == null || p === "application/x-www-form-urlencoded") ? (I = p ?? "application/x-www-form-urlencoded", g = {
form: b.map((o) => ({
const B = C(e, !1, ["G", "get"]);
E.length > 0 && B ? c.push(...E) : E.length > 0 && (d == null || d === "application/x-www-form-urlencoded") ? (I = d ?? "application/x-www-form-urlencoded", g = {
params: E.map((o) => ({
...o,
name: decodeURIComponent(o.name || ""),
value: decodeURIComponent(o.value || "")
}))
}, i.push({
name: "Content-Type",
value: "application/x-www-form-urlencoded",
enabled: !0
})) : b.length > 0 ? (I = p === "application/json" || p === "text/xml" || p === "text/plain" ? p : "other", g = {
text: b.map(({ name: o, value: l }) => o && l ? `${o}=${l}` : o || l).join("&")
}) : R.length && (I = p ?? "multipart/form-data", g = {
form: R
}, p == null && i.push({
name: "Content-Type",
value: "multipart/form-data",
enabled: !0
}));
let P = A(e, "", ["X", "request"]).toUpperCase();
return P === "" && g && (P = "text" in g || "form" in g ? "POST" : "GET"), {
}) : E.length > 0 ? (I = d === "application/json" || d === "text/xml" || d === "text/plain" ? d : "other", g = {
text: E.map(({ name: o, value: l }) => o && l ? `${o}=${l}` : o || l).join("&")
}) : T.length && (I = d ?? "multipart/form-data", g = {
form: T
});
let P = C(e, "", ["X", "request"]).toUpperCase();
return P === "" && g && (P = "text" in g || "params" in g ? "POST" : "GET"), {
id: N("http_request"),
model: "http_request",
workspaceId: s,
@@ -244,8 +233,8 @@ function te(n, s) {
url: m,
method: P,
headers: i,
authentication: O,
authenticationType: d,
authentication: A,
authenticationType: p,
body: g,
bodyType: I,
folderId: null,
@@ -264,17 +253,15 @@ const ne = (n) => {
c.startsWith("@") ? s.push({
name: m ?? "",
value: "",
filePath: c.slice(1),
enabled: !0
filePath: c.slice(1)
}) : s.push({
name: m ?? "",
value: e === "data-urlencode" ? encodeURIComponent(f ?? "") : f ?? "",
enabled: !0
value: e === "data-urlencode" ? encodeURIComponent(f ?? "") : f ?? ""
});
}
}
return s;
}, A = (n, s, e) => {
}, C = (n, s, e) => {
for (const t of e)
if (n[t] && n[t].length)
return n[t][0];

View File

@@ -131,7 +131,6 @@ function j(e) {
form: b(t.formdata).map(
(n) => n.src != null ? {
enabled: !n.disabled,
contentType: n.contentType ?? null,
name: n.key ?? "",
file: n.src ?? ""
} : {

View File

@@ -1,6 +1,6 @@
use std::fmt::Display;
use log::{debug, info, warn};
use log::warn;
use serde::{Deserialize, Serialize};
use serde_json::json;
use sqlx::types::JsonValue;
@@ -11,15 +11,11 @@ use crate::models::{
generate_id, get_key_value_int, get_key_value_string, set_key_value_int, set_key_value_string,
};
const NAMESPACE: &str = "analytics";
const NUM_LAUNCHES_KEY: &str = "num_launches";
// serializable
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "snake_case")]
pub enum AnalyticsResource {
App,
Appearance,
CookieJar,
Dialog,
Environment,
@@ -30,10 +26,9 @@ pub enum AnalyticsResource {
HttpRequest,
HttpResponse,
KeyValue,
Setting,
Sidebar,
Theme,
Workspace,
Setting,
}
impl AnalyticsResource {
@@ -98,19 +93,20 @@ pub struct LaunchEventInfo {
pub num_launches: i32,
}
pub async fn track_launch_event(app: &AppHandle) -> LaunchEventInfo {
pub async fn track_launch_event(app_handle: &AppHandle) -> LaunchEventInfo {
let namespace = "analytics";
let last_tracked_version_key = "last_tracked_version";
let mut info = LaunchEventInfo::default();
info.num_launches = get_num_launches(app).await + 1;
info.num_launches = get_key_value_int(app_handle, namespace, "num_launches", 0).await + 1;
info.previous_version =
get_key_value_string(app, NAMESPACE, last_tracked_version_key, "").await;
info.current_version = app.package_info().version.to_string();
get_key_value_string(app_handle, namespace, last_tracked_version_key, "").await;
info.current_version = app_handle.package_info().version.to_string();
if info.previous_version.is_empty() {
track_event(
app,
app_handle,
AnalyticsResource::App,
AnalyticsAction::LaunchFirst,
None,
@@ -120,10 +116,10 @@ pub async fn track_launch_event(app: &AppHandle) -> LaunchEventInfo {
info.launched_after_update = info.current_version != info.previous_version;
if info.launched_after_update {
track_event(
app,
app_handle,
AnalyticsResource::App,
AnalyticsAction::LaunchUpdate,
Some(json!({ NUM_LAUNCHES_KEY: info.num_launches })),
Some(json!({ "num_launches": info.num_launches })),
)
.await;
}
@@ -131,23 +127,23 @@ pub async fn track_launch_event(app: &AppHandle) -> LaunchEventInfo {
// Track a launch event in all cases
track_event(
app,
app_handle,
AnalyticsResource::App,
AnalyticsAction::Launch,
Some(json!({ NUM_LAUNCHES_KEY: info.num_launches })),
Some(json!({ "num_launches": info.num_launches })),
)
.await;
// Update key values
set_key_value_string(
app,
NAMESPACE,
app_handle,
namespace,
last_tracked_version_key,
info.current_version.as_str(),
)
.await;
set_key_value_int(app, NAMESPACE, NUM_LAUNCHES_KEY, info.num_launches).await;
set_key_value_int(app_handle, namespace, "num_launches", info.num_launches).await;
info
}
@@ -189,12 +185,15 @@ pub async fn track_event(
// Disable analytics actual sending in dev
if is_dev() {
debug!("track: {}", event);
// debug!("track: {} {} {:?}", event, attributes_json, params);
return;
}
if let Err(e) = req.send().await {
info!("Error sending analytics event: {}", e);
warn!(
"Error sending analytics event: {} {} {} {:?}",
e, event, attributes_json, params,
);
}
}
@@ -243,7 +242,3 @@ async fn get_id(app_handle: &AppHandle) -> String {
id
}
}
pub async fn get_num_launches(app: &AppHandle) -> i32 {
get_key_value_int(app, NAMESPACE, NUM_LAUNCHES_KEY, 0).await
}

View File

@@ -7,11 +7,11 @@ use std::sync::Arc;
use std::time::Duration;
use base64::Engine;
use http::header::{ACCEPT, USER_AGENT};
use http::{HeaderMap, HeaderName, HeaderValue, Method};
use http::header::{ACCEPT, USER_AGENT};
use log::{error, info, warn};
use reqwest::redirect::Policy;
use reqwest::{multipart, Url};
use reqwest::redirect::Policy;
use sqlx::types::{Json, JsonValue};
use tauri::{Manager, WebviewWindow};
use tokio::sync::oneshot;
@@ -89,24 +89,14 @@ pub async fn send_http_request(
let uri = match http::Uri::from_str(url_string.as_str()) {
Ok(u) => u,
Err(e) => {
return response_err(
response,
format!("Failed to parse URL \"{}\": {}", url_string, e.to_string()),
window,
)
.await;
return response_err(response, e.to_string(), window).await;
}
};
// Yes, we're parsing both URI and URL because they could return different errors
let url = match Url::from_str(uri.to_string().as_str()) {
Ok(u) => u,
Err(e) => {
return response_err(
response,
format!("Failed to parse URL \"{}\": {}", url_string, e.to_string()),
window,
)
.await;
return response_err(response, e.to_string(), window).await;
}
};
@@ -300,7 +290,7 @@ pub async fn send_http_request(
.unwrap_or_default();
let name = render::render(name_raw, &workspace, environment_ref);
let mut part = if file_path.is_empty() {
let part = if file_path.is_empty() {
multipart::Part::text(render::render(
value_raw,
&workspace,
@@ -321,24 +311,23 @@ pub async fn send_http_request(
.as_str()
.unwrap_or_default();
if !ct_raw.is_empty() {
let content_type = render::render(ct_raw, &workspace, environment_ref);
part = part
.mime_str(content_type.as_str())
.map_err(|e| e.to_string())?;
}
if !file_path.is_empty() {
let filename = PathBuf::from(file_path)
.file_name()
.unwrap_or_default()
.to_str()
.unwrap_or_default()
.to_string();
part = part.file_name(filename);
}
multipart_form = multipart_form.part(name, part);
multipart_form = multipart_form.part(
name,
if ct_raw.is_empty() {
part
} else {
let content_type = render::render(ct_raw, &workspace, environment_ref);
let filename = PathBuf::from(file_path)
.file_name()
.unwrap_or_default()
.to_str()
.unwrap_or_default()
.to_string();
part.file_name(filename)
.mime_str(content_type.as_str())
.map_err(|e| e.to_string())?
},
);
}
}
headers.remove("Content-Type"); // reqwest will add this automatically

View File

@@ -6,75 +6,70 @@ extern crate objc;
use std::collections::HashMap;
use std::env::current_dir;
use std::fs;
use std::fs::{create_dir_all, read_to_string, File};
use std::fs::{create_dir_all, File, read_to_string};
use std::path::PathBuf;
use std::process::exit;
use std::str::FromStr;
use std::time::Duration;
use ::http::uri::InvalidUri;
use ::http::Uri;
use ::http::uri::InvalidUri;
use base64::Engine;
use fern::colors::ColoredLevelConfig;
use log::{debug, error, info, warn};
use rand::random;
use serde_json::{json, Value};
use sqlx::{Pool, Sqlite, SqlitePool};
use sqlx::migrate::Migrator;
use sqlx::sqlite::SqliteConnectOptions;
use sqlx::types::Json;
use sqlx::{Pool, Sqlite, SqlitePool};
use tauri::{AppHandle, RunEvent, State, WebviewUrl, WebviewWindow};
use tauri::{Manager, WindowEvent};
use tauri::path::BaseDirectory;
#[cfg(target_os = "macos")]
use tauri::TitleBarStyle;
use tauri::{AppHandle, LogicalSize, RunEvent, State, WebviewUrl, WebviewWindow};
use tauri::{Manager, WindowEvent};
use tauri_plugin_log::{fern, Target, TargetKind};
use tauri_plugin_shell::ShellExt;
use tokio::sync::Mutex;
use tokio::time::sleep;
use ::grpc::{Code, deserialize_message, serialize_message, ServiceDefinition};
use ::grpc::manager::{DynamicMessage, GrpcHandle};
use ::grpc::{deserialize_message, serialize_message, Code, ServiceDefinition};
use window_ext::TrafficLightWindowExt;
use crate::analytics::{AnalyticsAction, AnalyticsResource};
use crate::grpc::metadata_to_map;
use crate::http_request::send_http_request;
use crate::http::send_http_request;
use crate::models::{
cancel_pending_grpc_connections, cancel_pending_responses, create_http_response,
delete_all_grpc_connections, delete_all_http_responses, delete_cookie_jar, delete_environment,
delete_folder, delete_grpc_connection, delete_grpc_request, delete_http_request,
delete_http_response, delete_workspace, duplicate_grpc_request, duplicate_http_request,
generate_model_id, get_cookie_jar, get_environment, get_folder, get_grpc_connection,
cancel_pending_grpc_connections, cancel_pending_responses, CookieJar,
create_http_response, delete_all_grpc_connections, delete_all_http_responses, delete_cookie_jar,
delete_environment, delete_folder, delete_grpc_connection, delete_grpc_request,
delete_http_request, delete_http_response, delete_workspace, duplicate_grpc_request,
duplicate_http_request, Environment, EnvironmentVariable, Folder, generate_model_id,
get_cookie_jar, get_environment, get_folder, get_grpc_connection,
get_grpc_request, get_http_request, get_http_response, get_key_value_raw,
get_or_create_settings, get_workspace, get_workspace_export_resources, list_cookie_jars,
list_environments, list_folders, list_grpc_connections, list_grpc_events, list_grpc_requests,
list_http_requests, list_responses, list_workspaces, set_key_value_raw, update_response_if_id,
update_settings, upsert_cookie_jar, upsert_environment, upsert_folder, upsert_grpc_connection,
upsert_grpc_event, upsert_grpc_request, upsert_http_request, upsert_workspace, CookieJar,
Environment, EnvironmentVariable, Folder, GrpcConnection, GrpcEvent, GrpcEventType,
GrpcRequest, HttpRequest, HttpResponse, KeyValue, ModelType, Settings, Workspace,
WorkspaceExportResources,
get_or_create_settings, get_workspace, get_workspace_export_resources, GrpcConnection, GrpcEvent,
GrpcEventType, GrpcRequest, HttpRequest, HttpRequestHeader, HttpResponse,
KeyValue, list_cookie_jars, list_environments, list_folders, list_grpc_connections,
list_grpc_events, list_grpc_requests, list_http_requests, list_responses, list_workspaces,
ModelType, set_key_value_raw, Settings, update_response_if_id, update_settings, upsert_cookie_jar,
upsert_environment, upsert_folder, upsert_grpc_connection, upsert_grpc_event, upsert_grpc_request, upsert_http_request, upsert_workspace,
Workspace, WorkspaceExportResources,
};
use crate::notifications::YaakNotifier;
use crate::plugin::{run_plugin_export_curl, run_plugin_import, ImportResult};
use crate::plugin::{ImportResult, run_plugin_export_curl, run_plugin_import};
use crate::render::render_request;
use crate::updates::{UpdateMode, YaakUpdater};
use crate::updates::{update_mode_from_str, UpdateMode, YaakUpdater};
use crate::window_menu::app_menu;
mod analytics;
mod grpc;
mod http_request;
mod http;
mod models;
mod notifications;
mod plugin;
mod render;
#[cfg(target_os = "macos")]
mod tauri_plugin_mac_window;
mod updates;
mod window_ext;
mod window_menu;
const DEFAULT_WINDOW_WIDTH: f64 = 1100.0;
const DEFAULT_WINDOW_HEIGHT: f64 = 600.0;
async fn migrate_db(app_handle: &AppHandle, db: &Mutex<Pool<Sqlite>>) -> Result<(), String> {
let pool = &*db.lock().await;
let p = app_handle
@@ -112,16 +107,6 @@ async fn cmd_metadata(app_handle: AppHandle) -> Result<AppMetaData, ()> {
});
}
#[tauri::command]
async fn cmd_dismiss_notification(
app: AppHandle,
notification_id: &str,
yaak_notifier: State<'_, Mutex<YaakNotifier>>,
) -> Result<(), String> {
info!("SEEN? {notification_id}");
yaak_notifier.lock().await.seen(&app, notification_id).await
}
#[tauri::command]
async fn cmd_grpc_reflect(
request_id: &str,
@@ -750,16 +735,16 @@ async fn cmd_import_data(
) -> Result<WorkspaceExportResources, String> {
let mut result: Option<ImportResult> = None;
let plugins = vec![
"importer-postman",
"importer-insomnia",
"importer-yaak",
"importer-insomnia",
"importer-postman",
"importer-curl",
];
let file = read_to_string(file_path)
let file = fs::read_to_string(file_path)
.unwrap_or_else(|_| panic!("Unable to read file {}", file_path));
let file_contents = file.as_str();
for plugin_name in plugins {
let v = run_plugin_import(&w.app_handle(), plugin_name, file_contents)
let v = plugin::run_plugin_import(&w.app_handle(), plugin_name, file_contents)
.await
.map_err(|e| e.to_string())?;
if let Some(r) = v {
@@ -1187,12 +1172,30 @@ async fn cmd_duplicate_grpc_request(id: &str, w: WebviewWindow) -> Result<GrpcRe
#[tauri::command]
async fn cmd_create_http_request(
request: HttpRequest,
workspace_id: &str,
name: &str,
sort_priority: f64,
folder_id: Option<&str>,
method: Option<&str>,
headers: Option<Vec<HttpRequestHeader>>,
body_type: Option<&str>,
w: WebviewWindow,
) -> Result<HttpRequest, String> {
upsert_http_request(&w, request)
.await
.map_err(|e| e.to_string())
upsert_http_request(
&w,
HttpRequest {
workspace_id: workspace_id.to_string(),
name: name.to_string(),
folder_id: folder_id.map(|s| s.to_string()),
body_type: body_type.map(|s| s.to_string()),
method: method.map(|s| s.to_string()).unwrap_or("GET".to_string()),
headers: Json(headers.unwrap_or_default()),
sort_priority,
..Default::default()
},
)
.await
.map_err(|e| e.to_string())
}
#[tauri::command]
@@ -1293,15 +1296,6 @@ async fn cmd_update_folder(folder: Folder, w: WebviewWindow) -> Result<Folder, S
upsert_folder(&w, folder).await.map_err(|e| e.to_string())
}
#[tauri::command]
async fn cmd_write_file_dev(pathname: &str, contents: &str) -> Result<(), String> {
if !is_dev() {
panic!("Cannot write arbitrary files when not in dev mode");
}
fs::write(pathname, contents).map_err(|e| e.to_string())
}
#[tauri::command]
async fn cmd_delete_folder(w: WebviewWindow, folder_id: &str) -> Result<Folder, String> {
delete_folder(&w, folder_id)
@@ -1491,8 +1485,6 @@ async fn cmd_list_workspaces(w: WebviewWindow) -> Result<Vec<Workspace>, String>
&w,
Workspace {
name: "Yaak".to_string(),
setting_follow_redirects: true,
setting_validate_certificates: true,
..Default::default()
},
)
@@ -1505,19 +1497,8 @@ async fn cmd_list_workspaces(w: WebviewWindow) -> Result<Vec<Workspace>, String>
}
#[tauri::command]
async fn cmd_new_window(app_handle: AppHandle, url: &str) -> Result<(), String> {
create_window(&app_handle, url);
Ok(())
}
#[tauri::command]
async fn cmd_new_nested_window(
window: WebviewWindow,
url: &str,
label: &str,
title: &str,
) -> Result<(), String> {
create_nested_window(&window, label, url, title);
async fn cmd_new_window(window: WebviewWindow, url: &str) -> Result<(), String> {
create_window(&window.app_handle(), Some(url));
Ok(())
}
@@ -1544,26 +1525,14 @@ async fn cmd_check_for_updates(
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
let mut builder = tauri::Builder::default()
tauri::Builder::default()
.plugin(tauri_plugin_clipboard_manager::init())
.plugin(tauri_plugin_window_state::Builder::default().build())
.plugin(tauri_plugin_shell::init())
.plugin(tauri_plugin_updater::Builder::new().build())
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_os::init())
.plugin(tauri_plugin_fs::init());
#[cfg(target_os = "macos")]
{
builder = builder.plugin(tauri_plugin_mac_window::init());
}
#[cfg(target_os = "linux")]
{
builder = builder; // Don't complain about not being mut
}
builder
.plugin(tauri_plugin_fs::init())
.plugin(
tauri_plugin_log::Builder::default()
.targets([
@@ -1619,10 +1588,6 @@ pub fn run() {
let yaak_updater = YaakUpdater::new();
app.manage(Mutex::new(yaak_updater));
// Add notifier
let yaak_notifier = YaakNotifier::new();
app.manage(Mutex::new(yaak_notifier));
// Add GRPC manager
let grpc_handle = GrpcHandle::new(&app.app_handle());
app.manage(Mutex::new(grpc_handle));
@@ -1689,10 +1654,8 @@ pub fn run() {
cmd_list_http_responses,
cmd_list_workspaces,
cmd_metadata,
cmd_new_nested_window,
cmd_new_window,
cmd_request_to_curl,
cmd_dismiss_notification,
cmd_send_ephemeral_request,
cmd_send_http_request,
cmd_set_key_value,
@@ -1705,24 +1668,27 @@ pub fn run() {
cmd_update_http_request,
cmd_update_settings,
cmd_update_workspace,
cmd_write_file_dev,
])
.register_uri_scheme_protocol("yaak", |_app, _req| {
debug!("Testing yaak protocol");
tauri::http::Response::builder()
.body("Success".as_bytes().to_vec())
.unwrap()
})
.build(tauri::generate_context!())
.expect("error while running tauri application")
.run(|app_handle, event| {
match event {
RunEvent::Ready => {
create_window(app_handle, "/");
let w = create_window(app_handle, None);
// if let Err(e) = w.restore_state(StateFlags::all()) {
// error!("Failed to restore window state {}", e);
// }
let h = app_handle.clone();
tauri::async_runtime::spawn(async move {
let info = analytics::track_launch_event(&h).await;
debug!("Launched Yaak {:?}", info);
// Wait for window render and give a chance for the user to notice
if info.launched_after_update && info.num_launches > 1 {
sleep(std::time::Duration::from_secs(5)).await;
let _ = w.emit("show_changelog", true);
}
});
}
RunEvent::WindowEvent {
@@ -1737,16 +1703,6 @@ pub fn run() {
let update_mode = get_update_mode(&h).await;
_ = val.lock().await.check(&h, update_mode).await;
});
let h = app_handle.clone();
tauri::async_runtime::spawn(async move {
tokio::time::sleep(Duration::from_millis(4000)).await;
let val: State<'_, Mutex<YaakNotifier>> = h.state();
let mut n = val.lock().await;
if let Err(e) = n.check(&h).await {
warn!("Failed to check for notifications {}", e)
}
});
}
_ => {}
};
@@ -1764,30 +1720,33 @@ fn is_dev() -> bool {
}
}
fn create_nested_window(
window: &WebviewWindow,
label: &str,
url: &str,
title: &str,
) -> WebviewWindow {
info!("Create new nested window label={label}");
fn create_window(handle: &AppHandle, url: Option<&str>) -> WebviewWindow {
let menu = app_menu(handle).unwrap();
handle.set_menu(menu).expect("Failed to set app menu");
let window_num = handle.webview_windows().len();
let window_id = format!("wnd_{}", window_num);
let mut win_builder = tauri::WebviewWindowBuilder::new(
window,
format!("nested_{}_{}", window.label(), label),
WebviewUrl::App(url.into()),
handle,
window_id,
WebviewUrl::App(url.unwrap_or_default().into()),
)
.resizable(true)
.fullscreen(false)
.disable_drag_drop_handler() // Required for frontend Dnd on windows
.title(title)
.parent(&window)
.unwrap()
.inner_size(DEFAULT_WINDOW_WIDTH * 0.7, DEFAULT_WINDOW_HEIGHT * 0.9);
.inner_size(1100.0, 600.0)
.position(
// Randomly offset so windows don't stack exactly
100.0 + random::<f64>() * 30.0,
100.0 + random::<f64>() * 30.0,
)
.title(handle.package_info().name.to_string());
// Add macOS-only things
#[cfg(target_os = "macos")]
{
win_builder = win_builder
// .menu(app_menu)
.hidden_title(true)
.title_bar_style(TitleBarStyle::Overlay);
}
@@ -1795,56 +1754,17 @@ fn create_nested_window(
// Add non-MacOS things
#[cfg(not(target_os = "macos"))]
{
// Doesn't seem to work from Rust, here, so we do it in JS
win_builder = win_builder.decorations(false);
}
let win = win_builder.build().expect("failed to build window");
win
}
// Tauri doesn't support shadows when hiding decorations, so we add our own
// #[cfg(any(windows, target_os = "macos"))]
// set_shadow(&win, true).unwrap();
fn create_window(handle: &AppHandle, url: &str) -> WebviewWindow {
#[allow(unused_variables)]
let menu = app_menu(handle).unwrap();
// This causes the window to not be clickable (in AppImage), so disable on Linux
#[cfg(not(target_os = "linux"))]
handle.set_menu(menu).expect("Failed to set app menu");
let window_num = handle.webview_windows().len();
let label = format!("main_{}", window_num);
info!("Create new window label={label}");
let mut win_builder =
tauri::WebviewWindowBuilder::new(handle, label, WebviewUrl::App(url.into()))
.resizable(true)
.fullscreen(false)
.disable_drag_drop_handler() // Required for frontend Dnd on windows
.inner_size(DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT)
.position(
// Randomly offset so windows don't stack exactly
100.0 + random::<f64>() * 30.0,
100.0 + random::<f64>() * 30.0,
)
.title(handle.package_info().name.to_string());
// Add macOS-only things
#[cfg(target_os = "macos")]
{
win_builder = win_builder
.hidden_title(true)
.title_bar_style(TitleBarStyle::Overlay);
}
// Add non-MacOS things
#[cfg(not(target_os = "macos"))]
{
// Doesn't seem to work from Rust, here, so we do it in main.tsx
win_builder = win_builder.decorations(false);
}
let win = win_builder.build().expect("failed to build window");
let webview_window = win.clone();
let win2 = win.clone();
win.on_menu_event(move |w, event| {
if !w.is_focused().unwrap() {
return;
@@ -1853,45 +1773,54 @@ fn create_window(handle: &AppHandle, url: &str) -> WebviewWindow {
match event.id().0.as_str() {
"quit" => exit(0),
"close" => w.close().unwrap(),
"zoom_reset" => w.emit("zoom_reset", true).unwrap(),
"zoom_in" => w.emit("zoom_in", true).unwrap(),
"zoom_out" => w.emit("zoom_out", true).unwrap(),
"zoom_reset" => w.emit("zoom", 0).unwrap(),
"zoom_in" => w.emit("zoom", 1).unwrap(),
"zoom_out" => w.emit("zoom", -1).unwrap(),
"settings" => w.emit("settings", true).unwrap(),
"duplicate_request" => w.emit("duplicate_request", true).unwrap(),
"refresh" => win2.eval("location.reload()").unwrap(),
"open_feedback" => {
_ = webview_window
_ = win2
.app_handle()
.shell()
.open("https://yaak.canny.io", None)
}
// Commands for development
"dev.reset_size" => webview_window
.set_size(LogicalSize::new(
DEFAULT_WINDOW_WIDTH,
DEFAULT_WINDOW_HEIGHT,
))
.unwrap(),
"dev.refresh" => webview_window.eval("location.reload()").unwrap(),
"dev.generate_theme_css" => {
w.emit("generate_theme_css", true).unwrap();
}
"dev.toggle_devtools" => {
if webview_window.is_devtools_open() {
webview_window.close_devtools();
"toggle_devtools" => {
if win2.is_devtools_open() {
win2.close_devtools();
} else {
webview_window.open_devtools();
win2.open_devtools();
}
}
_ => {}
}
});
let win3 = win.clone();
win.on_window_event(move |e| {
let apply_offset = || {
win3.position_traffic_lights();
};
match e {
WindowEvent::Resized(..) => apply_offset(),
WindowEvent::ThemeChanged(..) => apply_offset(),
WindowEvent::Focused(..) => apply_offset(),
WindowEvent::ScaleFactorChanged { .. } => apply_offset(),
WindowEvent::CloseRequested { .. } => {
// api.prevent_close();
}
_ => {}
}
});
win.position_traffic_lights();
win
}
async fn get_update_mode(h: &AppHandle) -> UpdateMode {
let settings = get_or_create_settings(h).await;
UpdateMode::new(settings.update_channel.as_str())
update_mode_from_str(settings.update_channel.as_str())
}
fn safe_uri(endpoint: &str) -> Result<Uri, InvalidUri> {

View File

@@ -52,13 +52,7 @@ pub struct Settings {
pub updated_at: NaiveDateTime,
pub theme: String,
pub appearance: String,
pub theme_dark: String,
pub theme_light: String,
pub update_channel: String,
pub interface_font_size: i64,
pub interface_scale: i64,
pub editor_font_size: i64,
pub editor_soft_wrap: bool,
}
#[derive(sqlx::FromRow, Debug, Clone, Serialize, Deserialize, Default)]
@@ -889,9 +883,7 @@ async fn get_settings(mgr: &impl Manager<Wry>) -> Result<Settings, sqlx::Error>
Settings,
r#"
SELECT
id, model, created_at, updated_at, theme, appearance,
theme_dark, theme_light, update_channel,
interface_font_size, interface_scale, editor_font_size, editor_soft_wrap
id, model, created_at, updated_at, theme, appearance, update_channel
FROM settings
WHERE id = 'default'
"#,
@@ -927,19 +919,12 @@ pub async fn update_settings(
sqlx::query!(
r#"
UPDATE settings SET (
theme, appearance, theme_dark, theme_light, update_channel,
interface_font_size, interface_scale, editor_font_size, editor_soft_wrap
) = (?, ?, ?, ?, ?, ?, ?, ?, ?) WHERE id = 'default';
theme, appearance, update_channel
) = (?, ?, ?) WHERE id = 'default';
"#,
settings.theme,
settings.appearance,
settings.theme_dark,
settings.theme_light,
settings.update_channel,
settings.interface_font_size,
settings.interface_scale,
settings.editor_font_size,
settings.editor_soft_wrap,
settings.update_channel
)
.execute(&db)
.await?;

View File

@@ -1,99 +0,0 @@
use std::time::SystemTime;
use chrono::{Duration, NaiveDateTime, Utc};
use http::Method;
use log::debug;
use serde::{Deserialize, Serialize};
use tauri::{AppHandle, Manager};
use crate::analytics::get_num_launches;
use crate::models::{get_key_value_raw, set_key_value_raw};
// Check for updates every hour
const MAX_UPDATE_CHECK_SECONDS: u64 = 60 * 60;
const KV_NAMESPACE: &str = "notifications";
const KV_KEY: &str = "seen";
// Create updater struct
pub struct YaakNotifier {
last_check: SystemTime,
}
#[derive(sqlx::FromRow, Debug, Clone, Serialize, Deserialize, Default)]
#[serde(default, rename_all = "camelCase")]
pub struct YaakNotification {
timestamp: NaiveDateTime,
id: String,
message: String,
action: Option<YaakNotificationAction>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(default, rename_all = "camelCase")]
pub struct YaakNotificationAction {
label: String,
url: String,
}
impl YaakNotifier {
pub fn new() -> Self {
Self {
last_check: SystemTime::UNIX_EPOCH,
}
}
pub async fn seen(&mut self, app: &AppHandle, id: &str) -> Result<(), String> {
let mut seen = get_kv(app).await?;
seen.push(id.to_string());
debug!("Marked notification as seen {}", id);
let seen_json = serde_json::to_string(&seen).map_err(|e| e.to_string())?;
set_key_value_raw(app, KV_NAMESPACE, KV_KEY, seen_json.as_str()).await;
Ok(())
}
pub async fn check(&mut self, app: &AppHandle) -> Result<(), String> {
let ignore_check = self.last_check.elapsed().unwrap().as_secs() < MAX_UPDATE_CHECK_SECONDS;
if ignore_check {
return Ok(());
}
self.last_check = SystemTime::now();
let num_launches = get_num_launches(app).await;
let info = app.package_info().clone();
let req = reqwest::Client::default()
.request(Method::GET, "https://notify.yaak.app/notifications")
.query(&[
("version", info.version.to_string()),
("launches", num_launches.to_string()),
]);
let resp = req.send().await.map_err(|e| e.to_string())?;
let notification = resp
.json::<YaakNotification>()
.await
.map_err(|e| e.to_string())?;
let age = notification
.timestamp
.signed_duration_since(Utc::now().naive_utc());
let seen = get_kv(app).await?;
if seen.contains(&notification.id) || (age > Duration::days(1)) {
debug!("Already seen notification {}", notification.id);
return Ok(());
}
debug!("Got notification {:?}", notification);
let _ = app.emit("notification", notification.clone());
Ok(())
}
}
async fn get_kv(app: &AppHandle) -> Result<Vec<String>, String> {
match get_key_value_raw(app, "notifications", "seen").await {
None => Ok(Vec::new()),
Some(v) => serde_json::from_str(&v.value).map_err(|e| e.to_string()),
}
}

View File

@@ -1,16 +1,16 @@
use std::rc::Rc;
use boa_engine::builtins::promise::PromiseState;
use boa_engine::{
js_string, module::SimpleModuleLoader, property::Attribute, Context, JsNativeError, JsValue,
Module, Source,
Context, js_string, JsNativeError, JsValue, Module, module::SimpleModuleLoader,
property::Attribute, Source,
};
use boa_engine::builtins::promise::PromiseState;
use boa_runtime::Console;
use log::{debug, error};
use serde::{Deserialize, Serialize};
use serde_json::json;
use tauri::path::BaseDirectory;
use tauri::{AppHandle, Manager};
use tauri::path::BaseDirectory;
use crate::models::{HttpRequest, WorkspaceExportResources};

View File

@@ -1,450 +0,0 @@
use hex_color::HexColor;
use objc::{msg_send, sel, sel_impl};
use rand::{distributions::Alphanumeric, Rng};
use tauri::{
plugin::{Builder, TauriPlugin},
Manager, Runtime, Window, WindowEvent,
};
const WINDOW_CONTROL_PAD_X: f64 = 13.0;
const WINDOW_CONTROL_PAD_Y: f64 = 18.0;
struct UnsafeWindowHandle(*mut std::ffi::c_void);
unsafe impl Send for UnsafeWindowHandle {}
unsafe impl Sync for UnsafeWindowHandle {}
pub fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::new("mac_window")
.on_window_ready(|window| {
#[cfg(target_os = "macos")]
{
setup_traffic_light_positioner(&window);
let h = window.app_handle();
let window_for_theme = window.clone();
let id1 = h.listen("yaak_bg_changed", move |ev| {
let payload = serde_json::from_str::<&str>(ev.payload()).unwrap().trim();
let color = HexColor::parse_rgb(payload).unwrap();
update_window_theme(window_for_theme.clone(), color);
});
let window_for_title = window.clone();
let id2 = h.listen("yaak_title_changed", move |ev| {
let payload = serde_json::from_str::<&str>(ev.payload()).unwrap().trim();
update_window_title(window_for_title.clone(), payload.to_string());
});
let h = h.clone();
window.on_window_event(move |e| {
match e {
WindowEvent::Destroyed => {
h.unlisten(id1);
h.unlisten(id2);
}
_ => {}
};
});
}
return;
})
.build()
}
#[cfg(target_os = "macos")]
fn update_window_title<R: Runtime>(window: Window<R>, title: String) {
use cocoa::{appkit::NSWindow, base::nil, foundation::NSString};
unsafe {
let window_handle = UnsafeWindowHandle(window.ns_window().unwrap());
let window2 = window.clone();
let label = window.label().to_string();
let _ = window.run_on_main_thread(move || {
let win_title = NSString::alloc(nil).init_str(&title);
let handle = window_handle;
NSWindow::setTitle_(handle.0 as cocoa::base::id, win_title);
position_traffic_lights(
UnsafeWindowHandle(window2.ns_window().expect("Failed to create window handle")),
WINDOW_CONTROL_PAD_X,
WINDOW_CONTROL_PAD_Y,
label,
);
});
}
}
#[cfg(target_os = "macos")]
fn update_window_theme<R: Runtime>(window: Window<R>, color: HexColor) {
use cocoa::appkit::{
NSAppearance, NSAppearanceNameVibrantDark, NSAppearanceNameVibrantLight, NSWindow,
};
let brightness = (color.r as u64 + color.g as u64 + color.b as u64) / 3;
let label = window.label().to_string();
unsafe {
let window_handle = UnsafeWindowHandle(window.ns_window().unwrap());
let window2 = window.clone();
let _ = window.run_on_main_thread(move || {
let handle = window_handle;
let selected_appearance = if brightness >= 128 {
NSAppearance(NSAppearanceNameVibrantLight)
} else {
NSAppearance(NSAppearanceNameVibrantDark)
};
NSWindow::setAppearance(handle.0 as cocoa::base::id, selected_appearance);
position_traffic_lights(
UnsafeWindowHandle(window2.ns_window().expect("Failed to create window handle")),
WINDOW_CONTROL_PAD_X,
WINDOW_CONTROL_PAD_Y,
label,
);
});
}
}
#[cfg(target_os = "macos")]
fn position_traffic_lights(ns_window_handle: UnsafeWindowHandle, x: f64, y: f64, label: String) {
if label.starts_with("nested_") {
return;
}
use cocoa::appkit::{NSView, NSWindow, NSWindowButton};
use cocoa::foundation::NSRect;
let ns_window = ns_window_handle.0 as cocoa::base::id;
unsafe {
let close = ns_window.standardWindowButton_(NSWindowButton::NSWindowCloseButton);
let miniaturize =
ns_window.standardWindowButton_(NSWindowButton::NSWindowMiniaturizeButton);
let zoom = ns_window.standardWindowButton_(NSWindowButton::NSWindowZoomButton);
let title_bar_container_view = close.superview().superview();
let close_rect: NSRect = msg_send![close, frame];
let button_height = close_rect.size.height;
let title_bar_frame_height = button_height + y;
let mut title_bar_rect = NSView::frame(title_bar_container_view);
title_bar_rect.size.height = title_bar_frame_height;
title_bar_rect.origin.y = NSView::frame(ns_window).size.height - title_bar_frame_height;
let _: () = msg_send![title_bar_container_view, setFrame: title_bar_rect];
let window_buttons = vec![close, miniaturize, zoom];
let space_between = NSView::frame(miniaturize).origin.x - NSView::frame(close).origin.x;
for (i, button) in window_buttons.into_iter().enumerate() {
let mut rect: NSRect = NSView::frame(button);
rect.origin.x = x + (i as f64 * space_between);
button.setFrameOrigin(rect.origin);
}
}
}
#[cfg(target_os = "macos")]
#[derive(Debug)]
struct WindowState<R: Runtime> {
window: Window<R>,
}
#[cfg(target_os = "macos")]
pub fn setup_traffic_light_positioner<R: Runtime>(window: &Window<R>) {
use cocoa::appkit::NSWindow;
use cocoa::base::{id, BOOL};
use cocoa::delegate;
use cocoa::foundation::NSUInteger;
use objc::runtime::{Object, Sel};
use std::ffi::c_void;
position_traffic_lights(
UnsafeWindowHandle(window.ns_window().expect("Failed to create window handle")),
WINDOW_CONTROL_PAD_X,
WINDOW_CONTROL_PAD_Y,
window.label().to_string(),
);
// Ensure they stay in place while resizing the window.
fn with_window_state<R: Runtime, F: FnOnce(&mut WindowState<R>) -> T, T>(
this: &Object,
func: F,
) {
let ptr = unsafe {
let x: *mut c_void = *this.get_ivar("app_box");
&mut *(x as *mut WindowState<R>)
};
func(ptr);
}
unsafe {
let ns_win = window
.ns_window()
.expect("NS Window should exist to mount traffic light delegate.")
as id;
let current_delegate: id = ns_win.delegate();
extern "C" fn on_window_should_close(this: &Object, _cmd: Sel, sender: id) -> BOOL {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
msg_send![super_del, windowShouldClose: sender]
}
}
extern "C" fn on_window_will_close(this: &Object, _cmd: Sel, notification: id) {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
let _: () = msg_send![super_del, windowWillClose: notification];
}
}
extern "C" fn on_window_did_resize<R: Runtime>(this: &Object, _cmd: Sel, notification: id) {
unsafe {
with_window_state(&*this, |state: &mut WindowState<R>| {
let id = state
.window
.ns_window()
.expect("NS window should exist on state to handle resize")
as id;
position_traffic_lights(
UnsafeWindowHandle(id as *mut c_void),
WINDOW_CONTROL_PAD_X,
WINDOW_CONTROL_PAD_Y,
state.window.label().to_string(),
);
});
let super_del: id = *this.get_ivar("super_delegate");
let _: () = msg_send![super_del, windowDidResize: notification];
}
}
extern "C" fn on_window_did_move(this: &Object, _cmd: Sel, notification: id) {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
let _: () = msg_send![super_del, windowDidMove: notification];
}
}
extern "C" fn on_window_did_change_backing_properties(
this: &Object,
_cmd: Sel,
notification: id,
) {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
let _: () = msg_send![super_del, windowDidChangeBackingProperties: notification];
}
}
extern "C" fn on_window_did_become_key(this: &Object, _cmd: Sel, notification: id) {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
let _: () = msg_send![super_del, windowDidBecomeKey: notification];
}
}
extern "C" fn on_window_did_resign_key(this: &Object, _cmd: Sel, notification: id) {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
let _: () = msg_send![super_del, windowDidResignKey: notification];
}
}
extern "C" fn on_dragging_entered(this: &Object, _cmd: Sel, notification: id) -> BOOL {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
msg_send![super_del, draggingEntered: notification]
}
}
extern "C" fn on_prepare_for_drag_operation(
this: &Object,
_cmd: Sel,
notification: id,
) -> BOOL {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
msg_send![super_del, prepareForDragOperation: notification]
}
}
extern "C" fn on_perform_drag_operation(this: &Object, _cmd: Sel, sender: id) -> BOOL {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
msg_send![super_del, performDragOperation: sender]
}
}
extern "C" fn on_conclude_drag_operation(this: &Object, _cmd: Sel, notification: id) {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
let _: () = msg_send![super_del, concludeDragOperation: notification];
}
}
extern "C" fn on_dragging_exited(this: &Object, _cmd: Sel, notification: id) {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
let _: () = msg_send![super_del, draggingExited: notification];
}
}
extern "C" fn on_window_will_use_full_screen_presentation_options(
this: &Object,
_cmd: Sel,
window: id,
proposed_options: NSUInteger,
) -> NSUInteger {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
msg_send![super_del, window: window willUseFullScreenPresentationOptions: proposed_options]
}
}
extern "C" fn on_window_did_enter_full_screen<R: Runtime>(
this: &Object,
_cmd: Sel,
notification: id,
) {
unsafe {
with_window_state(&*this, |state: &mut WindowState<R>| {
state
.window
.emit("did-enter-fullscreen", ())
.expect("Failed to emit event");
});
let super_del: id = *this.get_ivar("super_delegate");
let _: () = msg_send![super_del, windowDidEnterFullScreen: notification];
}
}
extern "C" fn on_window_will_enter_full_screen<R: Runtime>(
this: &Object,
_cmd: Sel,
notification: id,
) {
unsafe {
with_window_state(&*this, |state: &mut WindowState<R>| {
state
.window
.emit("will-enter-fullscreen", ())
.expect("Failed to emit event");
});
let super_del: id = *this.get_ivar("super_delegate");
let _: () = msg_send![super_del, windowWillEnterFullScreen: notification];
}
}
extern "C" fn on_window_did_exit_full_screen<R: Runtime>(
this: &Object,
_cmd: Sel,
notification: id,
) {
unsafe {
with_window_state(&*this, |state: &mut WindowState<R>| {
state
.window
.emit("did-exit-fullscreen", ())
.expect("Failed to emit event");
let id = state.window.ns_window().expect("Failed to emit event") as id;
position_traffic_lights(
UnsafeWindowHandle(id as *mut c_void),
WINDOW_CONTROL_PAD_X,
WINDOW_CONTROL_PAD_Y,
state.window.label().to_string(),
);
});
let super_del: id = *this.get_ivar("super_delegate");
let _: () = msg_send![super_del, windowDidExitFullScreen: notification];
}
}
extern "C" fn on_window_will_exit_full_screen<R: Runtime>(
this: &Object,
_cmd: Sel,
notification: id,
) {
unsafe {
with_window_state(&*this, |state: &mut WindowState<R>| {
state
.window
.emit("will-exit-fullscreen", ())
.expect("Failed to emit event");
});
let super_del: id = *this.get_ivar("super_delegate");
let _: () = msg_send![super_del, windowWillExitFullScreen: notification];
}
}
extern "C" fn on_window_did_fail_to_enter_full_screen(
this: &Object,
_cmd: Sel,
window: id,
) {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
let _: () = msg_send![super_del, windowDidFailToEnterFullScreen: window];
}
}
extern "C" fn on_effective_appearance_did_change(
this: &Object,
_cmd: Sel,
notification: id,
) {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
let _: () = msg_send![super_del, effectiveAppearanceDidChange: notification];
}
}
extern "C" fn on_effective_appearance_did_changed_on_main_thread(
this: &Object,
_cmd: Sel,
notification: id,
) {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
let _: () = msg_send![
super_del,
effectiveAppearanceDidChangedOnMainThread: notification
];
}
}
// Are we de-allocing this properly ? (I miss safe Rust :( )
let window_label = window.label().to_string();
let app_state = WindowState {
window: window.clone(),
};
let app_box = Box::into_raw(Box::new(app_state)) as *mut c_void;
let random_str: String = rand::thread_rng()
.sample_iter(&Alphanumeric)
.take(20)
.map(char::from)
.collect();
// We need to ensure we have a unique delegate name, otherwise we will panic while trying to create a duplicate
// delegate with the same name.
let delegate_name = format!("windowDelegate_{}_{}", window_label, random_str);
ns_win.setDelegate_(delegate!(&delegate_name, {
window: id = ns_win,
app_box: *mut c_void = app_box,
toolbar: id = cocoa::base::nil,
super_delegate: id = current_delegate,
(windowShouldClose:) => on_window_should_close as extern fn(&Object, Sel, id) -> BOOL,
(windowWillClose:) => on_window_will_close as extern fn(&Object, Sel, id),
(windowDidResize:) => on_window_did_resize::<R> as extern fn(&Object, Sel, id),
(windowDidMove:) => on_window_did_move as extern fn(&Object, Sel, id),
(windowDidChangeBackingProperties:) => on_window_did_change_backing_properties as extern fn(&Object, Sel, id),
(windowDidBecomeKey:) => on_window_did_become_key as extern fn(&Object, Sel, id),
(windowDidResignKey:) => on_window_did_resign_key as extern fn(&Object, Sel, id),
(draggingEntered:) => on_dragging_entered as extern fn(&Object, Sel, id) -> BOOL,
(prepareForDragOperation:) => on_prepare_for_drag_operation as extern fn(&Object, Sel, id) -> BOOL,
(performDragOperation:) => on_perform_drag_operation as extern fn(&Object, Sel, id) -> BOOL,
(concludeDragOperation:) => on_conclude_drag_operation as extern fn(&Object, Sel, id),
(draggingExited:) => on_dragging_exited as extern fn(&Object, Sel, id),
(window:willUseFullScreenPresentationOptions:) => on_window_will_use_full_screen_presentation_options as extern fn(&Object, Sel, id, NSUInteger) -> NSUInteger,
(windowDidEnterFullScreen:) => on_window_did_enter_full_screen::<R> as extern fn(&Object, Sel, id),
(windowWillEnterFullScreen:) => on_window_will_enter_full_screen::<R> as extern fn(&Object, Sel, id),
(windowDidExitFullScreen:) => on_window_did_exit_full_screen::<R> as extern fn(&Object, Sel, id),
(windowWillExitFullScreen:) => on_window_will_exit_full_screen::<R> as extern fn(&Object, Sel, id),
(windowDidFailToEnterFullScreen:) => on_window_did_fail_to_enter_full_screen as extern fn(&Object, Sel, id),
(effectiveAppearanceDidChange:) => on_effective_appearance_did_change as extern fn(&Object, Sel, id),
(effectiveAppearanceDidChangedOnMainThread:) => on_effective_appearance_did_changed_on_main_thread as extern fn(&Object, Sel, id)
}))
}
}

View File

@@ -1,4 +1,3 @@
use std::fmt::{Display, Formatter};
use std::time::SystemTime;
use log::info;
@@ -19,28 +18,6 @@ pub struct YaakUpdater {
pub enum UpdateMode {
Stable,
Beta,
Alpha,
}
impl Display for UpdateMode {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let s = match self {
UpdateMode::Stable => "stable",
UpdateMode::Beta => "beta",
UpdateMode::Alpha => "alpha",
};
write!(f, "{}", s)
}
}
impl UpdateMode {
pub fn new(mode: &str) -> UpdateMode {
match mode {
"beta" => UpdateMode::Beta,
"alpha" => UpdateMode::Alpha,
_ => UpdateMode::Stable,
}
}
}
impl YaakUpdater {
@@ -56,16 +33,24 @@ impl YaakUpdater {
) -> Result<bool, tauri_plugin_updater::Error> {
self.last_update_check = SystemTime::now();
info!("Checking for updates mode={}", mode);
let update_mode = get_update_mode_str(mode);
let enabled = !is_dev();
info!(
"Checking for updates mode={} enabled={}",
update_mode, enabled
);
let update_check_result = app_handle
if !enabled {
return Ok(false);
}
match app_handle
.updater_builder()
.header("X-Update-Mode", mode.to_string())?
.header("X-Update-Mode", update_mode)?
.build()?
.check()
.await;
match update_check_result {
.await
{
Ok(Some(update)) => {
let h = app_handle.clone();
app_handle
@@ -74,8 +59,6 @@ impl YaakUpdater {
"{} is available. Would you like to download and install it now?",
update.version
))
.ok_button_label("Download")
.cancel_button_label("Later")
.title("Update Available")
.show(|confirmed| {
if !confirmed {
@@ -87,8 +70,6 @@ impl YaakUpdater {
if h.dialog()
.message("Would you like to restart the app?")
.title("Update Installed")
.ok_button_label("Restart")
.cancel_button_label("Later")
.blocking_show()
{
h.restart();
@@ -118,11 +99,20 @@ impl YaakUpdater {
return Ok(false);
}
// Don't check if dev
if is_dev() {
return Ok(false);
}
self.force_check(app_handle, mode).await
}
}
pub fn update_mode_from_str(mode: &str) -> UpdateMode {
match mode {
"beta" => UpdateMode::Beta,
_ => UpdateMode::Stable,
}
}
fn get_update_mode_str(mode: UpdateMode) -> &'static str {
match mode {
UpdateMode::Stable => "stable",
UpdateMode::Beta => "beta",
}
}

View File

@@ -0,0 +1,53 @@
use tauri::WebviewWindow;
const TRAFFIC_LIGHT_OFFSET_X: f64 = 13.0;
const TRAFFIC_LIGHT_OFFSET_Y: f64 = 18.0;
pub trait TrafficLightWindowExt {
fn position_traffic_lights(&self);
}
impl TrafficLightWindowExt for WebviewWindow {
#[cfg(not(target_os = "macos"))]
fn position_traffic_lights(&self) {
// No-op on other platforms
}
#[cfg(target_os = "macos")]
fn position_traffic_lights(&self) {
use cocoa::appkit::{NSView, NSWindow, NSWindowButton};
use cocoa::foundation::NSRect;
let window = self.ns_window().unwrap() as cocoa::base::id;
let x = TRAFFIC_LIGHT_OFFSET_X;
let y = TRAFFIC_LIGHT_OFFSET_Y;
unsafe {
let close = window.standardWindowButton_(NSWindowButton::NSWindowCloseButton);
let miniaturize =
window.standardWindowButton_(NSWindowButton::NSWindowMiniaturizeButton);
let zoom = window.standardWindowButton_(NSWindowButton::NSWindowZoomButton);
let title_bar_container_view = close.superview().superview();
let close_rect: NSRect = msg_send![close, frame];
let button_height = close_rect.size.height;
let title_bar_frame_height = button_height + y;
let mut title_bar_rect = NSView::frame(title_bar_container_view);
title_bar_rect.size.height = title_bar_frame_height;
title_bar_rect.origin.y = NSView::frame(window).size.height - title_bar_frame_height;
let _: () = msg_send![title_bar_container_view, setFrame: title_bar_rect];
let window_buttons = vec![close, miniaturize, zoom];
let space_between = NSView::frame(miniaturize).origin.x - NSView::frame(close).origin.x;
for (i, button) in window_buttons.into_iter().enumerate() {
let mut rect: NSRect = NSView::frame(button);
rect.origin.x = x + (i as f64 * space_between);
button.setFrameOrigin(rect.origin);
}
}
}
}

View File

@@ -126,16 +126,12 @@ pub fn app_menu(app_handle: &AppHandle) -> tauri::Result<Menu<Wry>> {
"Develop",
true,
&[
&MenuItemBuilder::with_id("dev.refresh".to_string(), "Refresh")
&MenuItemBuilder::with_id("refresh".to_string(), "Refresh")
.accelerator("CmdOrCtrl+Shift+r")
.build(app_handle)?,
&MenuItemBuilder::with_id("dev.toggle_devtools".to_string(), "Open Devtools")
&MenuItemBuilder::with_id("toggle_devtools".to_string(), "Open Devtools")
.accelerator("CmdOrCtrl+Option+i")
.build(app_handle)?,
&MenuItemBuilder::with_id("dev.reset_size".to_string(), "Reset Size")
.build(app_handle)?,
&MenuItemBuilder::with_id("dev.generate_theme_css".to_string(), "Generate Theme CSS")
.build(app_handle)?,
],
)?,
],

View File

@@ -1,40 +1,71 @@
{
"productName": "yaak",
"version": "2024.5.1",
"identifier": "app.yaak.desktop",
"build": {
"beforeBuildCommand": "npm run build",
"beforeDevCommand": "npm run dev",
"devUrl": "http://localhost:1420",
"frontendDist": "../dist"
},
"productName": "Yaak",
"version": "2024.4.0-beta.2",
"identifier": "app.yaak.desktop",
"app": {
"withGlobalTauri": false,
"security": {
"assetProtocol": {
"enable": true,
"scope": {
"allow": [
"$APPDATA/responses/*"
]
}
"scope": [
"$APPDATA/responses/*"
]
}
}
},
"plugins": {
"deep-link": {
"mobile": [],
"desktop": {
"schemes": [
"yaak"
]
}
},
"updater": {
"endpoints": [
"https://update.yaak.app/check/{{target}}/{{arch}}/{{current_version}}"
],
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEMxRDJFREQ1MjExQjdGN0IKUldSN2Z4c2gxZTNTd1FHNCtmYnFXMHVVQzhuNkJOM1cwOFBodmdLall3ckhKenpKUytHSTR1MlkK"
},
"allowlist": {
"all": false,
"os": {
"allow-os-type": true
},
"fs": {
"readFile": true,
"scope": [
"$RESOURCE/*",
"$APPDATA/responses/*"
]
},
"shell": {
"all": false,
"open": true,
"sidecar": true,
"scope": [
{
"name": "protoc",
"sidecar": true,
"args": true
}
]
},
"window": {
"close": true,
"maximize": true,
"minimize": true,
"setDecorations": true,
"setTitle": true,
"startDragging": true,
"unmaximize": true
},
"dialog": {
"all": false,
"open": true,
"save": true
},
"path": {
"all": true
}
}
},
"bundle": {
@@ -50,13 +81,13 @@
"icons/release/icon.icns",
"icons/release/icon.ico"
],
"longDescription": "A cross-platform desktop app for interacting with REST, GraphQL, and gRPC",
"longDescription": "The best cross-platform visual API client",
"resources": [
"migrations/*",
"plugins/*",
"protoc-vendored/include/*"
],
"shortDescription": "Desktop API client",
"shortDescription": "The best API client",
"targets": [
"deb",
"appimage",
@@ -65,9 +96,6 @@
"dmg",
"updater"
],
"iOS": {
"developmentTeam": "7PU3P6ELJ8"
},
"macOS": {
"exceptionDomain": "",
"entitlements": "macos/entitlements.plist",

View File

@@ -3,7 +3,6 @@ import { routePaths, useAppRoutes } from '../hooks/useAppRoutes';
import { DefaultLayout } from './DefaultLayout';
import { RedirectToLatestWorkspace } from './RedirectToLatestWorkspace';
import RouteError from './RouteError';
import { Settings } from './Settings/Settings';
import Workspace from './Workspace';
const router = createBrowserRouter([
@@ -37,12 +36,6 @@ const router = createBrowserRouter([
path: '/workspaces/:workspaceId/environments/:environmentId/requests/:requestId',
element: <RedirectLegacyEnvironmentURLs />,
},
{
path: routePaths.workspaceSettings({
workspaceId: ':workspaceId',
}),
element: <Settings />,
},
],
},
]);

View File

@@ -30,14 +30,15 @@ export function BinaryFileEditor({
const handleClick = async () => {
await ignoreContentType.set(false);
const selected = await open({
const path = await open({
title: 'Select File',
multiple: false,
});
if (selected == null) {
return;
if (path) {
onChange({ filePath: path });
} else {
onChange({ filePath: undefined });
}
onChange({ filePath: selected.path });
};
const filePath = typeof body.filePath === 'string' ? body.filePath : undefined;
@@ -45,11 +46,11 @@ export function BinaryFileEditor({
return (
<VStack space={2}>
<HStack space={2}>
<Button variant="border" color="secondary" size="sm" onClick={handleClick}>
<HStack space={2} alignItems="center">
<Button variant="border" color="gray" size="sm" onClick={handleClick}>
Choose File
</Button>
<div className="text-sm font-mono truncate rtl pr-3 text-fg">
<div className="text-xs font-mono truncate rtl pr-3 text-gray-800">
{/* Special character to insert ltr text in rtl element without making things wonky */}
&#x200E;
{filePath ?? 'Select File'}
@@ -57,22 +58,22 @@ export function BinaryFileEditor({
</HStack>
{filePath != null && mimeType !== contentType && !ignoreContentType.value && (
<Banner className="mt-3 !py-5">
<div className="mb-4 text-center">
<div className="text-sm mb-4 text-center">
<div>Set Content-Type header</div>
<InlineCode>{mimeType}</InlineCode> for current request?
</div>
<HStack space={1.5} justifyContent="center">
<Button size="sm" variant="border" onClick={() => ignoreContentType.set(true)}>
Ignore
</Button>
<Button
variant="solid"
color="primary"
size="sm"
color="gray"
size="xs"
onClick={() => onChangeContentType(mimeType)}
>
Set Header
</Button>
<Button size="xs" variant="border" onClick={() => ignoreContentType.set(true)}>
Ignore
</Button>
</HStack>
</Banner>
)}

View File

@@ -1,6 +1,6 @@
import classNames from 'classnames';
import type { ReactNode } from 'react';
import { useCallback, useMemo, useState } from 'react';
import { useMemo, useCallback, useState } from 'react';
import { useActiveEnvironmentId } from '../hooks/useActiveEnvironmentId';
import { useAppRoutes } from '../hooks/useAppRoutes';
import { getRecentEnvironments } from '../hooks/useRecentEnvironments';
@@ -117,8 +117,8 @@ function CommandPaletteItem({
<button
onClick={onClick}
className={classNames(
'w-full h-xs flex items-center rounded px-1.5 text-fg-subtle',
active && 'bg-background-highlight-secondary text-fg',
'w-full h-xs flex items-center rounded px-1.5 text-gray-600',
active && 'bg-highlightSecondary text-gray-800',
)}
>
{children}

View File

@@ -28,7 +28,7 @@ export const CookieDialog = function ({ cookieJarId }: Props) {
return (
<div className="pb-2">
<table className="w-full text-sm mb-auto min-w-full max-w-full divide-y divide-background-highlight">
<table className="w-full text-xs mb-auto min-w-full max-w-full divide-y">
<thead>
<tr>
<th className="py-2 text-left">Domain</th>
@@ -36,13 +36,13 @@ export const CookieDialog = function ({ cookieJarId }: Props) {
<th className="py-2 pl-4"></th>
</tr>
</thead>
<tbody className="divide-y divide-background-highlight-secondary">
<tbody className="divide-y">
{cookieJar?.cookies.map((c) => (
<tr key={c.domain + c.raw_cookie}>
<td className="py-2 select-text cursor-text font-mono font-semibold max-w-0">
{cookieDomain(c)}
</td>
<td className="py-2 pl-4 select-text cursor-text font-mono text-fg-subtle whitespace-nowrap overflow-x-auto max-w-[200px] hide-scrollbars">
<td className="py-2 pl-4 select-text cursor-text font-mono text-gray-700 whitespace-nowrap overflow-x-auto max-w-[200px] hide-scrollbars">
{c.raw_cookie}
</td>
<td className="max-w-0 w-10">
@@ -53,6 +53,11 @@ export const CookieDialog = function ({ cookieJarId }: Props) {
title="Delete"
className="ml-auto"
onClick={async () => {
console.log(
'DELETE COOKIE',
c,
cookieJar.cookies.filter((c2) => c2 !== c).length,
);
await updateCookieJar.mutateAsync({
...cookieJar,
cookies: cookieJar.cookies.filter((c2) => c2 !== c),

View File

@@ -2,15 +2,12 @@ import { useCreateDropdownItems } from '../hooks/useCreateDropdownItems';
import type { DropdownProps } from './core/Dropdown';
import { Dropdown } from './core/Dropdown';
interface Props extends Omit<DropdownProps, 'items'> {
interface Props {
hideFolder?: boolean;
children: DropdownProps['children'];
}
export function CreateDropdown({ hideFolder, children, ...props }: Props) {
export function CreateDropdown({ hideFolder, children }: Props) {
const items = useCreateDropdownItems({ hideFolder, hideIcons: true });
return (
<Dropdown items={items} {...props}>
{children}
</Dropdown>
);
return <Dropdown items={items}>{children}</Dropdown>;
}

View File

@@ -2,26 +2,12 @@ import { Outlet } from 'react-router-dom';
import { DialogProvider } from './DialogContext';
import { GlobalHooks } from './GlobalHooks';
import { ToastProvider } from './ToastContext';
import classNames from 'classnames';
import { useOsInfo } from '../hooks/useOsInfo';
import { motion } from 'framer-motion';
export function DefaultLayout() {
const osInfo = useOsInfo();
return (
<DialogProvider>
<ToastProvider>
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.1, delay: 0.1 }}
className={classNames(
'w-full h-full',
osInfo?.osType === 'linux' && 'border border-background-highlight-secondary',
)}
>
<Outlet />
</motion.div>
<Outlet />
<GlobalHooks />
</ToastProvider>
</DialogProvider>

View File

@@ -14,7 +14,7 @@ export const DropMarker = memo(
'relative w-full h-0 overflow-visible pointer-events-none',
)}
>
<div className="absolute z-50 left-2 right-2 -bottom-[0.1rem] h-[0.2rem] bg-fg-primary rounded-full" />
<div className="absolute z-50 left-2 right-2 -bottom-[0.1rem] h-[0.2rem] bg-blue-500/50 rounded-full" />
</div>
);
},

View File

@@ -1,6 +1,5 @@
import classNames from 'classnames';
import type { ReactNode } from 'react';
import React from 'react';
interface Props {
children: ReactNode;
@@ -12,8 +11,7 @@ export function EmptyStateText({ children, className }: Props) {
<div
className={classNames(
className,
'rounded-lg border border-dashed border-background-highlight',
'h-full py-2 text-fg-subtler flex items-center justify-center italic',
'rounded-lg border border-dashed border-highlight h-full py-2 text-gray-400 flex items-center justify-center',
)}
>
{children}

View File

@@ -71,8 +71,8 @@ export const EnvironmentActionsDropdown = memo(function EnvironmentActionsDropdo
size="sm"
className={classNames(
className,
'text-fg !px-2 truncate',
activeEnvironment == null && 'text-fg-subtler italic',
'text-gray-800 !px-2 truncate',
activeEnvironment == null && 'text-opacity-disabled italic',
)}
{...buttonProps}
>

View File

@@ -68,7 +68,7 @@ export const EnvironmentEditDialog = function ({ initialEnvironment }: Props) {
color="custom"
title="Add sub environment"
icon="plusCircle"
iconClassName="text-fg-subtler group-hover:text-fg-subtle"
iconClassName="text-gray-500 group-hover:text-gray-700"
className="group"
onClick={handleCreateEnvironment}
/>
@@ -97,7 +97,7 @@ export const EnvironmentEditDialog = function ({ initialEnvironment }: Props) {
secondSlot={() =>
activeWorkspace != null && (
<EnvironmentEditor
className="pt-2 border-l border-background-highlight-secondary"
className="pt-2 border-l border-highlight"
environment={selectedEnvironment}
workspace={activeWorkspace}
/>
@@ -175,7 +175,7 @@ const EnvironmentEditor = function ({
<Heading className="w-full flex items-center gap-1">
<div>{environment?.name ?? 'Global Variables'}</div>
<IconButton
iconClassName="text-fg-subtler"
iconClassName="text-gray-600"
size="sm"
icon={valueVisibility.value ? 'eye' : 'eyeClosed'}
title={valueVisibility.value ? 'Hide Values' : 'Reveal Values'}
@@ -244,7 +244,7 @@ function SidebarButton({
size="xs"
className={classNames(
'w-full',
active ? 'text-fg bg-background-active' : 'text-fg-subtle hover:text-fg',
active ? 'text-gray-800 bg-highlightSecondary' : 'text-gray-600 hover:text-gray-700',
)}
justify="start"
onClick={onClick}
@@ -281,7 +281,7 @@ function SidebarButton({
},
},
{
key: 'delete-environment',
key: 'delete',
variant: 'danger',
label: 'Delete',
leftSlot: <Icon icon="trash" size="sm" />,

View File

@@ -1,6 +1,6 @@
import { invoke } from '@tauri-apps/api/core';
import { save } from '@tauri-apps/plugin-dialog';
import { useCallback, useMemo, useState } from 'react';
import { useState } from 'react';
import slugify from 'slugify';
import type { Workspace } from '../lib/models';
import { count } from '../lib/pluralize';
@@ -10,26 +10,16 @@ import { HStack, VStack } from './core/Stacks';
interface Props {
onHide: () => void;
onSuccess: (path: string) => void;
activeWorkspace: Workspace;
workspaces: Workspace[];
}
export function ExportDataDialog({
onHide,
onSuccess,
activeWorkspace,
workspaces: allWorkspaces,
}: Props) {
export function ExportDataDialog({ onHide, activeWorkspace, workspaces: allWorkspaces }: Props) {
const [selectedWorkspaces, setSelectedWorkspaces] = useState<Record<string, boolean>>({
[activeWorkspace.id]: true,
});
// Put active workspace first
const workspaces = useMemo(
() => [activeWorkspace, ...allWorkspaces.filter((w) => w.id !== activeWorkspace.id)],
[activeWorkspace, allWorkspaces],
);
const workspaces = [activeWorkspace, ...allWorkspaces.filter((w) => w.id !== activeWorkspace.id)];
const handleToggleAll = () => {
setSelectedWorkspaces(
@@ -37,7 +27,7 @@ export function ExportDataDialog({
);
};
const handleExport = useCallback(async () => {
const handleExport = async () => {
const ids = Object.keys(selectedWorkspaces).filter((k) => selectedWorkspaces[k]);
const workspace = ids.length === 1 ? workspaces.find((w) => w.id === ids[0]) : undefined;
const slug = workspace ? slugify(workspace.name, { lower: true }) : 'workspaces';
@@ -51,8 +41,7 @@ export function ExportDataDialog({
await invoke('cmd_export_data', { workspaceIds: ids, exportPath });
onHide();
onSuccess(exportPath);
}, [onHide, onSuccess, selectedWorkspaces, workspaces]);
};
const allSelected = workspaces.every((w) => selectedWorkspaces[w.id]);
const numSelected = Object.values(selectedWorkspaces).filter(Boolean).length;
@@ -90,7 +79,7 @@ export function ExportDataDialog({
/>
</td>
<td
className="py-1 pl-4 text-fg whitespace-nowrap overflow-x-auto hide-scrollbars"
className="py-1 pl-4 text-gray-700 whitespace-nowrap overflow-x-auto hide-scrollbars"
onClick={() => setSelectedWorkspaces((prev) => ({ ...prev, [w.id]: !prev[w.id] }))}
>
{w.name} {w.id === activeWorkspace.id ? '(current workspace)' : ''}
@@ -100,7 +89,7 @@ export function ExportDataDialog({
</tbody>
</table>
<HStack space={2} justifyContent="end">
<Button className="focus" variant="border" onClick={onHide}>
<Button className="focus" color="gray" onClick={onHide}>
Cancel
</Button>
<Button
@@ -108,7 +97,7 @@ export function ExportDataDialog({
className="focus"
color="primary"
disabled={noneSelected}
onClick={() => handleExport()}
onClick={handleExport}
>
Export {count('Workspace', numSelected, { omitSingle: true, noneWord: 'Nothing' })}
</Button>

View File

@@ -30,8 +30,6 @@ export function FormUrlencodedEditor({ body, forceUpdateKey, onChange }: Props)
<PairEditor
valueAutocompleteVariables
nameAutocompleteVariables
namePlaceholder="entry_name"
valuePlaceholder="Value"
pairs={pairs}
onChange={handleChange}
forceUpdateKey={forceUpdateKey}

View File

@@ -1,54 +1,53 @@
import { useQueryClient } from '@tanstack/react-query';
import { getCurrent } from '@tauri-apps/api/webviewWindow';
import { useEffect } from 'react';
import { useClipboardText } from '../hooks/useClipboardText';
import { useLocation } from 'react-router-dom';
import { useCommandPalette } from '../hooks/useCommandPalette';
import { cookieJarsQueryKey } from '../hooks/useCookieJars';
import { environmentsQueryKey } from '../hooks/useEnvironments';
import { foldersQueryKey } from '../hooks/useFolders';
import { useGlobalCommands } from '../hooks/useGlobalCommands';
import { grpcConnectionsQueryKey } from '../hooks/useGrpcConnections';
import { grpcEventsQueryKey } from '../hooks/useGrpcEvents';
import { grpcRequestsQueryKey } from '../hooks/useGrpcRequests';
import { useHotKey } from '../hooks/useHotKey';
import { httpRequestsQueryKey } from '../hooks/useHttpRequests';
import { httpResponsesQueryKey } from '../hooks/useHttpResponses';
import { keyValueQueryKey } from '../hooks/useKeyValue';
import { useListenToTauriEvent } from '../hooks/useListenToTauriEvent';
import { useNotificationToast } from '../hooks/useNotificationToast';
import { useRecentEnvironments } from '../hooks/useRecentEnvironments';
import { useRecentRequests } from '../hooks/useRecentRequests';
import { useRecentWorkspaces } from '../hooks/useRecentWorkspaces';
import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey';
import { settingsQueryKey, useSettings } from '../hooks/useSettings';
import { useSyncThemeToDocument } from '../hooks/useSyncThemeToDocument';
import { settingsQueryKey } from '../hooks/useSettings';
import { useSyncAppearance } from '../hooks/useSyncAppearance';
import { useSyncWindowTitle } from '../hooks/useSyncWindowTitle';
import { workspacesQueryKey } from '../hooks/useWorkspaces';
import { useZoom } from '../hooks/useZoom';
import type { Model } from '../lib/models';
import { modelsEq } from '../lib/models';
import { catppuccinMacchiato } from '../lib/theme/themes/catppuccin';
import { githubLight } from '../lib/theme/themes/github';
import { hotdogStandDefault } from '../lib/theme/themes/hotdog-stand';
import { monokaiProDefault } from '../lib/theme/themes/monokai-pro';
import { rosePineDefault } from '../lib/theme/themes/rose-pine';
import { yaakDark } from '../lib/theme/themes/yaak';
import { getThemeCSS } from '../lib/theme/window';
import { setPathname } from '../lib/persistPathname';
const DEFAULT_FONT_SIZE = 16;
export function GlobalHooks() {
// Include here so they always update, even if no component references them
// Include here so they always update, even
// if no component references them
useRecentWorkspaces();
useRecentEnvironments();
useRecentRequests();
// Other useful things
useSyncThemeToDocument();
useSyncAppearance();
useSyncWindowTitle();
useGlobalCommands();
useCommandPalette();
useNotificationToast();
const queryClient = useQueryClient();
const { wasUpdatedExternally } = useRequestUpdateKey(null);
// Listen for location changes and update the pathname
const location = useLocation();
useEffect(() => {
setPathname(location.pathname).catch(console.error);
}, [location.pathname]);
interface ModelPayload {
model: Model;
windowLabel: string;
@@ -63,8 +62,6 @@ export function GlobalHooks() {
? httpResponsesQueryKey(model)
: model.model === 'folder'
? foldersQueryKey(model)
: model.model === 'environment'
? environmentsQueryKey(model)
: model.model === 'grpc_connection'
? grpcConnectionsQueryKey(model)
: model.model === 'grpc_event'
@@ -99,8 +96,10 @@ export function GlobalHooks() {
queryClient.setQueryData<Model[]>(queryKey, (values = []) => {
const index = values.findIndex((v) => modelsEq(v, model)) ?? -1;
if (index >= 0) {
// console.log('UPDATED', payload);
return [...values.slice(0, index), model, ...values.slice(index + 1)];
} else {
// console.log('CREATED', payload);
return pushToFront ? [model, ...(values ?? [])] : [...(values ?? []), model];
}
});
@@ -118,8 +117,6 @@ export function GlobalHooks() {
queryClient.setQueryData(httpResponsesQueryKey(model), removeById(model));
} else if (model.model === 'folder') {
queryClient.setQueryData(foldersQueryKey(model), removeById(model));
} else if (model.model === 'environment') {
queryClient.setQueryData(environmentsQueryKey(model), removeById(model));
} else if (model.model === 'grpc_request') {
queryClient.setQueryData(grpcRequestsQueryKey(model), removeById(model));
} else if (model.model === 'grpc_connection') {
@@ -135,42 +132,26 @@ export function GlobalHooks() {
}
});
const settings = useSettings();
useEffect(() => {
if (settings == null) {
return;
}
useListenToTauriEvent<number>(
'zoom',
({ payload: zoomDelta }) => {
const fontSize = parseFloat(window.getComputedStyle(document.documentElement).fontSize);
const { interfaceScale, interfaceFontSize, editorFontSize } = settings;
getCurrent().setZoom(interfaceScale).catch(console.error);
document.documentElement.style.setProperty('font-size', `${interfaceFontSize}px`);
document.documentElement.style.setProperty('--editor-font-size', `${editorFontSize}px`);
}, [settings]);
let newFontSize;
if (zoomDelta === 0) {
newFontSize = DEFAULT_FONT_SIZE;
} else if (zoomDelta > 0) {
newFontSize = Math.min(fontSize * 1.1, DEFAULT_FONT_SIZE * 5);
} else if (zoomDelta < 0) {
newFontSize = Math.max(fontSize * 0.9, DEFAULT_FONT_SIZE * 0.4);
}
// Handle Zoom. Note, Mac handles it in app menu, so need to also handle keyboard
// shortcuts for Windows/Linux
const zoom = useZoom();
useHotKey('app.zoom_in', () => zoom.zoomIn);
useListenToTauriEvent('zoom_in', () => zoom.zoomIn);
useHotKey('app.zoom_out', () => zoom.zoomOut);
useListenToTauriEvent('zoom_out', () => zoom.zoomOut);
useHotKey('app.zoom_reset', () => zoom.zoomReset);
useListenToTauriEvent('zoom_reset', () => zoom.zoomReset);
const [, copy] = useClipboardText();
useListenToTauriEvent('generate_theme_css', () => {
const themesCss = [
yaakDark,
monokaiProDefault,
rosePineDefault,
catppuccinMacchiato,
githubLight,
hotdogStandDefault,
]
.map(getThemeCSS)
.join('\n\n');
copy(themesCss);
});
document.documentElement.style.fontSize = `${newFontSize}px`;
},
{
target: { kind: 'WebviewWindow', label: getCurrent().label },
},
);
return null;
}

View File

@@ -88,7 +88,7 @@ export function GraphQLEditor({ defaultValue, onChange, baseRequest, ...extraEdi
<Button
key="introspection"
size="xs"
color={error ? 'danger' : 'secondary'}
color={error ? 'danger' : 'gray'}
isLoading={isLoading}
onClick={() => {
dialog.show({
@@ -105,7 +105,7 @@ export function GraphQLEditor({ defaultValue, onChange, baseRequest, ...extraEdi
refetch();
}}
className="ml-auto"
color="primary"
color="secondary"
size="sm"
>
Try Again

View File

@@ -98,10 +98,9 @@ export function GrpcConnectionLayout({ style }: Props) {
<div
style={style}
className={classNames(
'x-theme-responsePane',
'max-h-full h-full grid grid-rows-[minmax(0,1fr)] grid-cols-1',
'bg-background rounded-md border border-background-highlight',
'shadow relative',
'bg-gray-50 dark:bg-gray-100 rounded-md border border-highlight',
'shadow shadow-gray-100 dark:shadow-gray-0 relative',
)}
>
{grpc.go.error ? (

View File

@@ -2,17 +2,15 @@ import classNames from 'classnames';
import { format } from 'date-fns';
import type { CSSProperties } from 'react';
import React, { useEffect, useMemo, useState } from 'react';
import { useGrpcConnections } from '../hooks/useGrpcConnections';
import { useGrpcEvents } from '../hooks/useGrpcEvents';
import { usePinnedGrpcConnection } from '../hooks/usePinnedGrpcConnection';
import { useStateWithDeps } from '../hooks/useStateWithDeps';
import type { GrpcEvent, GrpcRequest } from '../lib/models';
import { Button } from './core/Button';
import { Icon } from './core/Icon';
import { JsonAttributeTree } from './core/JsonAttributeTree';
import { KeyValueRow, KeyValueRows } from './core/KeyValueRow';
import { Separator } from './core/Separator';
import { SplitLayout } from './core/SplitLayout';
import { HStack, VStack } from './core/Stacks';
import { HStack } from './core/Stacks';
import { EmptyStateText } from './EmptyStateText';
import { RecentConnectionsDropdown } from './RecentConnectionsDropdown';
@@ -31,10 +29,8 @@ interface Props {
export function GrpcConnectionMessagesPane({ style, methodType, activeRequest }: Props) {
const [activeEventId, setActiveEventId] = useState<string | null>(null);
const [showLarge, setShowLarge] = useStateWithDeps<boolean>(false, [activeRequest.id]);
const [showingLarge, setShowingLarge] = useState<boolean>(false);
const { activeConnection, connections, setPinnedConnectionId } =
usePinnedGrpcConnection(activeRequest);
const connections = useGrpcConnections(activeRequest.id ?? null);
const activeConnection = connections[0] ?? null;
const events = useGrpcEvents(activeConnection?.id ?? null);
const activeEvent = useMemo(
@@ -61,17 +57,19 @@ export function GrpcConnectionMessagesPane({ style, methodType, activeRequest }:
firstSlot={() =>
activeConnection && (
<div className="w-full grid grid-rows-[auto_minmax(0,1fr)] items-center">
<HStack className="pl-3 mb-1 font-mono">
<HStack space={2}>
<HStack className="pl-3 mb-1 font-mono" alignItems="center">
<HStack alignItems="center" space={2}>
<span>{events.length} messages</span>
{activeConnection.elapsed === 0 && (
<Icon icon="refresh" size="sm" spin className="text-fg-subtler" />
<Icon icon="refresh" size="sm" spin className="text-gray-600" />
)}
</HStack>
<RecentConnectionsDropdown
connections={connections}
activeConnection={activeConnection}
onPinnedConnectionId={setPinnedConnectionId}
onPinned={() => {
// todo
}}
/>
</HStack>
<div className="overflow-y-auto h-full">
@@ -104,30 +102,7 @@ export function GrpcConnectionMessagesPane({ style, methodType, activeRequest }:
<div className="mb-2 select-text cursor-text font-semibold">
Message {activeEvent.eventType === 'client_message' ? 'Sent' : 'Received'}
</div>
{!showLarge && activeEvent.content.length > 1000 * 1000 ? (
<VStack space={2} className="italic text-fg-subtler">
Message previews larger than 1MB are hidden
<div>
<Button
onClick={() => {
setShowingLarge(true);
setTimeout(() => {
setShowLarge(true);
setShowingLarge(false);
}, 500);
}}
isLoading={showingLarge}
color="secondary"
variant="border"
size="xs"
>
Try Showing
</Button>
</div>
</VStack>
) : (
<JsonAttributeTree attrValue={JSON.parse(activeEvent?.content ?? '{}')} />
)}
<JsonAttributeTree attrValue={JSON.parse(activeEvent?.content ?? '{}')} />
</>
) : (
<div className="h-full grid grid-rows-[auto_minmax(0,1fr)]">
@@ -136,7 +111,7 @@ export function GrpcConnectionMessagesPane({ style, methodType, activeRequest }:
{activeEvent.content}
</div>
{activeEvent.error && (
<div className="select-text cursor-text text-sm font-mono py-1 text-fg-warning">
<div className="text-xs font-mono py-1 text-orange-700">
{activeEvent.error}
</div>
)}
@@ -181,21 +156,21 @@ function EventRow({
className={classNames(
'w-full grid grid-cols-[auto_minmax(0,3fr)_auto] gap-2 items-center text-left',
'px-1.5 py-1 font-mono cursor-default group focus:outline-none rounded',
isActive && '!bg-background-highlight-secondary !text-fg',
'text-fg-subtle hover:text-fg',
isActive && '!bg-highlight text-gray-900',
'text-gray-800 hover:text-gray-900',
)}
>
<Icon
className={
eventType === 'server_message'
? 'text-fg-info'
? 'text-blue-600'
: eventType === 'client_message'
? 'text-fg-primary'
? 'text-violet-600'
: eventType === 'error' || (status != null && status > 0)
? 'text-fg-danger'
? 'text-orange-600'
: eventType === 'connection_end'
? 'text-fg-success'
: 'text-fg-subtle'
? 'text-green-600'
: 'text-gray-700'
}
title={
eventType === 'server_message'
@@ -220,11 +195,15 @@ function EventRow({
: 'info'
}
/>
<div className={classNames('w-full truncate text-xs')}>
{content.slice(0, 1000)}
{error && <span className="text-fg-warning"> ({error})</span>}
<div className={classNames('w-full truncate text-2xs')}>
{content}
{error && (
<>
<span className="text-orange-600"> ({error})</span>
</>
)}
</div>
<div className={classNames('opacity-50 text-xs')}>
<div className={classNames('opacity-50 text-2xs')}>
{format(createdAt + 'Z', 'HH:mm:ss.SSS')}
</div>
</button>

View File

@@ -199,17 +199,17 @@ export function GrpcConnectionSetupPane({
label: 'Refresh',
type: 'default',
key: 'custom',
leftSlot: <Icon className="text-fg-subtler" size="sm" icon="refresh" />,
leftSlot: <Icon className="text-gray-600" size="sm" icon="refresh" />,
},
]}
>
<Button
size="sm"
variant="border"
rightSlot={<Icon className="text-fg-subtler" size="sm" icon="chevronDown" />}
rightSlot={<Icon className="text-gray-600" size="sm" icon="chevronDown" />}
disabled={isStreaming || services == null}
className={classNames(
'font-mono text-sm min-w-[5rem] !ring-0',
'font-mono text-xs min-w-[5rem] !ring-0',
paneSize < 400 && 'flex-1',
)}
>
@@ -221,14 +221,14 @@ export function GrpcConnectionSetupPane({
{isStreaming && (
<>
<IconButton
className="border border-background-highlight-secondary"
className="border border-highlight"
size="sm"
title="Cancel"
onClick={onCancel}
icon="x"
/>
<IconButton
className="border border-background-highlight-secondary"
className="border border-highlight"
size="sm"
title="Commit"
onClick={onCommit}
@@ -237,7 +237,7 @@ export function GrpcConnectionSetupPane({
</>
)}
<IconButton
className="border border-background-highlight-secondary"
className="border border-highlight"
size="sm"
title={isStreaming ? 'Connect' : 'Send'}
hotkeyAction="grpc_request.send"
@@ -247,7 +247,7 @@ export function GrpcConnectionSetupPane({
</>
) : (
<IconButton
className="border border-background-highlight-secondary"
className="border border-highlight"
size="sm"
title={methodType === 'unary' ? 'Send' : 'Connect'}
hotkeyAction="grpc_request.send"
@@ -275,6 +275,7 @@ export function GrpcConnectionSetupPane({
<GrpcEditor
onChange={handleChangeMessage}
services={services}
className="bg-gray-50"
reflectionError={reflectionError}
reflectionLoading={reflectionLoading}
request={activeRequest}

View File

@@ -133,12 +133,12 @@ export function GrpcEditor({
size="xs"
color={
reflectionLoading
? 'secondary'
? 'gray'
: reflectionUnavailable
? 'info'
? 'secondary'
: reflectionError
? 'danger'
: 'secondary'
: 'gray'
}
isLoading={reflectionLoading}
onClick={() => {

View File

@@ -40,16 +40,17 @@ export function GrpcProtoSelection({ requestId }: Props) {
<HStack space={2} justifyContent="start" className="flex-row-reverse">
<Button
color="primary"
size="sm"
onClick={async () => {
const selected = await open({
const files = await open({
title: 'Select Proto Files',
multiple: true,
filters: [{ name: 'Proto Files', extensions: ['proto'] }],
});
if (selected == null) {
if (files == null) {
return;
}
const newFiles = selected.map((f) => f.path).filter((p) => !protoFiles.includes(p));
const newFiles = files.map((f) => f.path).filter((p) => !protoFiles.includes(p));
await protoFilesKv.set([...protoFiles, ...newFiles]);
await grpc.reflect.refetch();
}}
@@ -59,7 +60,8 @@ export function GrpcProtoSelection({ requestId }: Props) {
<Button
isLoading={grpc.reflect.isFetching}
disabled={grpc.reflect.isFetching}
color="secondary"
color="gray"
size="sm"
onClick={() => grpc.reflect.refetch()}
>
Refresh Schema
@@ -101,24 +103,25 @@ export function GrpcProtoSelection({ requestId }: Props) {
)}
{protoFiles.length > 0 && (
<table className="w-full divide-y divide-background-highlight">
<table className="w-full divide-y">
<thead>
<tr>
<th className="text-fg-subtler">
<span className="font-mono">*.proto</span> Files
<th className="text-gray-600">
<span className="font-mono text-sm">*.proto</span> Files
</th>
<th></th>
</tr>
</thead>
<tbody className="divide-y divide-background-highlight">
<tbody className="divide-y">
{protoFiles.map((f, i) => (
<tr key={f + i} className="group">
<td className="pl-1 font-mono">{f.split('/').pop()}</td>
<td className="pl-1 text-sm font-mono">{f.split('/').pop()}</td>
<td className="w-0 py-0.5">
<IconButton
title="Remove file"
size="sm"
icon="trash"
className="ml-auto opacity-50 transition-opacity group-hover:opacity-100"
className="ml-auto opacity-30 transition-opacity group-hover:opacity-100"
onClick={async () => {
await protoFilesKv.set(protoFiles.filter((p) => p !== f));
}}

View File

@@ -1,38 +0,0 @@
import classNames from 'classnames';
import type { HTMLAttributes, ReactNode } from 'react';
import { useIsFullscreen } from '../hooks/useIsFullscreen';
import { useOsInfo } from '../hooks/useOsInfo';
interface HeaderSizeProps extends HTMLAttributes<HTMLDivElement> {
children?: ReactNode;
size: 'md' | 'lg';
ignoreStoplights?: boolean;
}
export function HeaderSize({
className,
style,
size,
ignoreStoplights,
...props
}: HeaderSizeProps) {
const platform = useOsInfo();
const fullscreen = useIsFullscreen();
const stoplightsVisible = platform?.osType === 'macos' && !fullscreen && !ignoreStoplights;
return (
<div
data-tauri-drag-region
style={style}
className={classNames(
className,
'pt-[1px] w-full border-b border-background-highlight min-w-0',
stoplightsVisible ? 'pl-20 pr-1' : 'pl-1',
size === 'md' && 'h-[27px]',
size === 'lg' && 'h-[38px]',
)}
>
{/* NOTE: This needs display:grid or else the element shrinks (even though scrollable) */}
<div className="h-full w-full overflow-x-auto hide-scrollbars grid" {...props} />
</div>
);
}

View File

@@ -1,43 +0,0 @@
import { motion } from 'framer-motion';
import React, { useState } from 'react';
import { useClipboardText } from '../hooks/useClipboardText';
import { useImportCurl } from '../hooks/useImportCurl';
import { Button } from './core/Button';
import { Icon } from './core/Icon';
export function ImportCurlButton() {
const [clipboardText] = useClipboardText();
const importCurl = useImportCurl({ clearClipboard: true });
const [isLoading, setIsLoading] = useState(false);
if (!clipboardText?.trim().startsWith('curl ')) {
return null;
}
return (
<motion.div
initial={{ opacity: 0, scale: 0 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ delay: 0.5 }}
>
<Button
size="xs"
variant="border"
color="primary"
leftSlot={<Icon icon="paste" size="sm" />}
isLoading={isLoading}
onClick={() => {
setIsLoading(true);
importCurl
.mutateAsync({
requestId: null, // Create request
command: clipboardText,
})
.finally(() => setIsLoading(false));
}}
>
Import Curl
</Button>
</motion.div>
);
}

View File

@@ -1,15 +0,0 @@
import type { ReactNode } from 'react';
import { useAppInfo } from '../hooks/useAppInfo';
interface Props {
children: ReactNode;
}
export function IsDev({ children }: Props) {
const appInfo = useAppInfo();
if (!appInfo?.isDev) {
return null;
}
return <>{children}</>;
}

View File

@@ -1,10 +1,10 @@
import { hotkeyActions } from '../hooks/useHotKey';
import { HotKeyList } from './core/HotKeyList';
export function KeyboardShortcutsDialog() {
export const KeyboardShortcutsDialog = () => {
return (
<div className="h-full w-full pb-2">
<HotKeyList hotkeys={hotkeyActions} />
</div>
);
}
};

View File

@@ -2,7 +2,6 @@ import classNames from 'classnames';
import FocusTrap from 'focus-trap-react';
import { motion } from 'framer-motion';
import type { ReactNode } from 'react';
import React from 'react';
import { Portal } from './Portal';
interface Props {
@@ -44,16 +43,10 @@ export function Overlay({
onClick={onClose}
className={classNames(
'absolute inset-0',
variant === 'default' && 'bg-background-backdrop backdrop-blur-sm',
variant === 'default' && 'bg-gray-600/30 dark:bg-black/30 backdrop-blur-sm',
)}
/>
{children}
{/* Show draggable region at the top */}
{/* TODO: Figure out tauri drag region and also make clickable still */}
{variant === 'default' && (
<div data-tauri-drag-region className="absolute top-0 left-0 h-md right-0" />
)}
<div className="bg-red-100">{children}</div>
</motion.div>
</FocusTrap>
)}

View File

@@ -1,7 +1,6 @@
import type { ReactNode } from 'react';
import { createPortal } from 'react-dom';
import { usePortal } from '../hooks/usePortal';
interface Props {
children: ReactNode;
name: string;

View File

@@ -11,17 +11,12 @@ import { HStack } from './core/Stacks';
interface Props {
connections: GrpcConnection[];
activeConnection: GrpcConnection;
onPinnedConnectionId: (id: string) => void;
onPinned: (r: GrpcConnection) => void;
}
export function RecentConnectionsDropdown({
activeConnection,
connections,
onPinnedConnectionId,
}: Props) {
export function RecentConnectionsDropdown({ activeConnection, connections, onPinned }: Props) {
const deleteConnection = useDeleteGrpcConnection(activeConnection?.id ?? null);
const deleteAllConnections = useDeleteGrpcConnections(activeConnection?.requestId);
const latestConnectionId = connections[0]?.id ?? 'n/a';
return (
<Dropdown
@@ -43,19 +38,19 @@ export function RecentConnectionsDropdown({
...connections.slice(0, 20).map((c) => ({
key: c.id,
label: (
<HStack space={2}>
<HStack space={2} alignItems="center">
{formatDistanceToNowStrict(c.createdAt + 'Z')} ago &bull;{' '}
<span className="font-mono text-sm">{c.elapsed}ms</span>
<span className="font-mono text-xs">{c.elapsed}ms</span>
</HStack>
),
leftSlot: activeConnection?.id === c.id ? <Icon icon="check" /> : <Icon icon="empty" />,
onSelect: () => onPinnedConnectionId(c.id),
onSelect: () => onPinned(c),
})),
]}
>
<IconButton
title="Show connection history"
icon={activeConnection?.id === latestConnectionId ? 'chevronDown' : 'pin'}
icon="chevronDown"
className="ml-auto"
size="sm"
iconSize="md"

View File

@@ -86,8 +86,8 @@ export function RecentRequestsDropdown({ className }: Pick<ButtonProps, 'classNa
hotkeyAction="request_switcher.toggle"
className={classNames(
className,
'text-fg truncate pointer-events-auto',
activeRequest === null && 'text-fg-subtler italic',
'text-gray-800 text-sm truncate pointer-events-auto',
activeRequest === null && 'text-opacity-disabled italic',
)}
>
{fallbackRequestName(activeRequest)}

Some files were not shown because too many files have changed in this diff Show More