Compare commits

...

763 Commits

Author SHA1 Message Date
Antonio Scandurra
4319745c52 zed 0.63.3 2022-11-08 18:23:01 +01:00
Antonio Scandurra
69d2b36788 Merge pull request #1862 from zed-industries/fix-catalina
Weakly link ReplayKit to ensure this library can be used on macOS 10.15
2022-11-08 18:19:48 +01:00
Joseph T Lyons
eebc785e4c zed 0.63.2 2022-11-04 18:35:09 -04:00
Kay Simmons
d109220e0d Merge pull request #1857 from zed-industries/fix-unicode-vim-left
fixes issue with left motion in vim mode clipping incorrectly
2022-11-04 18:33:11 -04:00
Nate Butler
a88a2e601d Swap the color of diagnostic underlines to fix low contrast issue. 2022-11-04 18:33:11 -04:00
Kay Simmons
7cefb16086 Merge pull request #1845 from zed-industries/vim-dd-fix
Vim dd fix
2022-11-04 18:33:11 -04:00
Joseph T. Lyons
c2c30f6615 Merge pull request #1855 from zed-industries/make-app-a-user-property-in-mixpanel
Make `App` a user property in Mixpanel
2022-11-04 14:45:15 -04:00
Max Brunsfeld
bf9a1091e3 zed 0.63.1 2022-11-04 09:30:49 -07:00
Max Brunsfeld
e1f1a706a6 Merge pull request #1851 from zed-industries/rust-let-else
Bump tree-sitter-rust for let-else, let-chains
2022-11-03 18:04:49 -07:00
Max Brunsfeld
75ebaabc2c Merge pull request #1853 from zed-industries/diagnostics-focus-loop
Fix infinite focus transfer loop in project diagnostics
2022-11-03 18:03:05 -07:00
Joseph T. Lyons
d608331f08 Merge pull request #1850 from zed-industries/add-automatic-annotations-for-mixpanel
Add automatic annotations for mixpanel
2022-11-03 13:28:00 -04:00
Max Brunsfeld
448c472ee6 v0.63.x preview 2022-11-02 10:22:52 -07:00
Joseph T. Lyons
370a6f3dbd Merge pull request #1842 from zed-industries/telemetry-corrections
Telemetry corrections
2022-11-02 12:36:48 -04:00
Joseph T Lyons
d8685baa47 Revert "Differentiate between first time app starts and subsequent ones" 2022-11-02 12:22:46 -04:00
Nate Butler
6a07f59d34 Merge pull request #1831 from zed-industries/theme-tweaks
Theme tweaks
2022-11-02 10:04:55 -04:00
Nate Butler
7981cd45ed Increase scrollbar width 2022-11-02 09:58:15 -04:00
Antonio Scandurra
66b1283c95 Merge pull request #1846 from zed-industries/dont-focus-notification-windows
Don't focus incoming call and project shared notification windows
2022-11-02 13:21:18 +00:00
Antonio Scandurra
d275474b23 Don't focus incoming call and project shared notification windows 2022-11-02 14:17:16 +01:00
Antonio Scandurra
86057ab071 Merge pull request #1843 from zed-industries/call-randomized-test
Model calls in randomized collaboration test
2022-11-02 13:03:34 +00:00
Joseph T Lyons
aafc3a9584 Make event name casing consistent with other event names 2022-11-01 23:19:55 -04:00
Joseph T Lyons
dc657a647e Remove Amplitude event tracking 2022-11-01 20:49:49 -04:00
Joseph T Lyons
e5f0965138 Differentiate between first time app starts and subsequent ones 2022-11-01 20:36:18 -04:00
Julia
b2b25acc4c Merge pull request #1841 from zed-industries/tab-activation-history
Avoid reordering items by adding an activation history to panes, and remove tab reordering hack
2022-11-01 14:46:45 -04:00
Antonio Scandurra
0b79950510 Don't hold the lock while yielding back to the executor in Client 2022-11-01 19:16:02 +01:00
Antonio Scandurra
d6d1e20f07 Ensure declining call doesn't accidentally leave a room 2022-11-01 18:48:08 +01:00
Julia
c58abf1b0b Add test for new tab order history behavior 2022-11-01 13:29:21 -04:00
Antonio Scandurra
88d2e2e277 Introduce calls to randomized collaboration test 2022-11-01 15:44:00 +01:00
Antonio Scandurra
946c92667f Don't drop fake LSP adapter's receiver before simulate ends 2022-11-01 14:28:01 +01:00
Antonio Scandurra
f54f653d42 Don't return an error when failing to send AddProjectCollaborator
This can happen when a peer has disconnected but we haven't yet been
able to acquire a lock to the store to clean up the state associated
with it.
2022-11-01 11:21:40 +01:00
Antonio Scandurra
ef72c75fab Honor MAX_PEERS env variable in randomized test 2022-11-01 10:24:26 +01:00
Antonio Scandurra
c6e52dbef7 Fix hang due to acquiring rng lock twice 2022-11-01 09:35:53 +01:00
Antonio Scandurra
62547e87dd Prevent randomized test from failing if another guest disconnects 2022-11-01 09:27:51 +01:00
Antonio Scandurra
eb6b545eeb Fix outstanding compiler errors in randomized collaboration test 2022-11-01 08:40:31 +01:00
Antonio Scandurra
4c4ebbfa19 Start removing distinction between host and guest in random collab test 2022-11-01 08:40:08 +01:00
Joseph T Lyons
61f31bf010 Fill in missing "app" field names on Mixpanel events 2022-10-31 19:18:35 -04:00
Joseph T Lyons
495fd151f5 Revert Amplitude's "app" name back to "platform"
This was unintentional.  We only want to rename the Mixpanel telemetry "platform" field to "app."  We want to keep it as "platform" on Amplitude because we want to keep using Amplitude for a bit, and the event fields should be the same.
2022-10-31 19:18:03 -04:00
Max Brunsfeld
482a5bb02a Merge pull request #1840 from zed-industries/build-themes-in-assets-crate
Generate themes before compiling the 'assets' crate
2022-10-31 14:18:28 -07:00
Kay Simmons
4e35b26365 Avoid reordering items by adding an activation history to panes, and remove tab reordering hack
Co-Authored-By: Julia Risley <julia@zed.dev>
2022-10-31 14:10:34 -07:00
Joseph T. Lyons
c180137e02 Merge pull request #1829 from zed-industries/add-release-channel-information-to-telemetry-events
Add release channel information to telemetry events
2022-10-31 16:42:28 -04:00
Max Brunsfeld
ef837232bc Generate themes before compiling the 'assets' crate 2022-10-31 13:25:12 -07:00
Max Brunsfeld
d0aa9f1c57 Merge pull request #1839 from zed-industries/contact-list-project-color
Don't use 'on' background color for projects in the contact list
2022-10-31 12:39:17 -07:00
Max Brunsfeld
aa549d1da7 Don't use 'on' color for projects in the contact list 2022-10-31 12:28:25 -07:00
Julia
259a758849 Merge pull request #1800 from zed-industries/go-to-diff-hunk
Add action to go to next/previous git diff in editor
2022-10-31 14:38:52 -04:00
Julia
7ac45379eb Layout git gutters inclusively 2022-10-31 14:35:42 -04:00
Max Brunsfeld
0940482c62 Merge pull request #1838 from zed-industries/tab-panic
Fix panic when hitting tab at the beginning of a line with mixed tab/…
2022-10-31 10:55:48 -07:00
Max Brunsfeld
9cbb698b96 Fix panic when hitting tab at the beginning of a line with mixed tab/space indent 2022-10-31 10:51:20 -07:00
Mikayla Maki
1820be4990 Adds a little spacing between the share button and the screenshare icon 2022-10-31 10:19:06 -07:00
Mikayla Maki
37ca232548 Remove annoyoing debug 2022-10-31 10:02:17 -07:00
Mikayla Maki
ea9b009a22 Fixed bug with cut entry active states 2022-10-31 09:55:52 -07:00
Nate Butler
dbc804669c Update ignored, cut entry styles in the project panel 2022-10-31 10:30:58 -04:00
Julia
c8fbc0d348 Slightly expand region hunk layout checks for folds 2022-10-28 19:05:29 -04:00
Julia
8361b4d47a Add test for go-to hunk and fix discovered bugs 2022-10-28 15:08:13 -04:00
Julia
ae2021e073 WIP start setting up test infrastructure for editor diff actions
Co-Authored-By: Kay Simmons <kay@zed.dev>
2022-10-28 15:08:13 -04:00
Julia
c4b21a0ab5 Add action to go to next/previous git diff in editor
Co-Authored-By: Kay Simmons <kay@zed.dev>
2022-10-28 15:08:13 -04:00
Mikayla Maki
8a095d0a55 Merge pull request #1833 from zed-industries/add-channel-to-db
Added channel info to database directories
2022-10-28 11:54:46 -07:00
Mikayla Maki
c0bf8fd6a8 Added channel to database directories 2022-10-28 11:50:26 -07:00
Mikayla Maki
14329980e1 Merge pull request #1832 from zed-industries/upgrade-migration-lib
Upgraded migration library to remove panic
2022-10-28 11:41:31 -07:00
Mikayla Maki
950626fe9e Upgraded migration library to remove panic 2022-10-28 11:36:41 -07:00
Mikayla Maki
8b7e587467 Removed stray test file 2022-10-28 10:48:54 -07:00
Mikayla Maki
552ebc0f29 Implemented direct styling for ignored and cut project panel entries 2022-10-28 10:45:45 -07:00
Nate Butler
9148e1d30a Update icons
- `x_mark_thin` combined into `x_mark`
- updated many icons
- remove unused icons
2022-10-28 12:59:05 -04:00
Max Brunsfeld
9156d488ca Merge pull request #1830 from zed-industries/auto-update-filename
Make auto-update handle an app bundle name other than 'Zed.app'
2022-10-27 16:47:34 -07:00
Max Brunsfeld
e1ac1675ea Avoid hard-coding app bundle filename in auto-updater 2022-10-27 16:44:07 -07:00
Max Brunsfeld
863250904b Avoid posting in Discord about preview releases (for now)
Co-authored-by: Joseph Lyons <joseph@zed.dev>
2022-10-27 15:43:00 -07:00
Joseph T Lyons
8a926c4a23 Make release_channel optional to fix tests
Co-Authored-By: Max Brunsfeld <maxbrunsfeld@gmail.com>
2022-10-27 18:06:34 -04:00
Kay Simmons
760cceb378 Merge pull request #1827 from zed-industries/fix-keymap-resolution-fallback
Keymap resolution fallbacks
2022-10-27 13:50:38 -07:00
K Simmons
c5650f9334 remove unnecessary comment 2022-10-27 13:29:57 -07:00
K Simmons
bf968707df upgrade existing test to match new expected behavior 2022-10-27 13:28:49 -07:00
Max Brunsfeld
31fa7ca90c Add livekit to the Procfile, update the README 2022-10-27 13:24:35 -07:00
Joseph T Lyons
309f401015 Rename all keys, in telemetry events, to be consistent with Mixpanels conventions 2022-10-27 16:19:21 -04:00
Max Brunsfeld
33d02cedd7 Run CI when pushing to release branches (e.g. 'v0.62.x') 2022-10-27 13:03:35 -07:00
Joseph T Lyons
daa75b5282 Add missing struct field
This must've gotten lost on the merging of main into this branch
2022-10-27 15:59:22 -04:00
Joseph T Lyons
36c64045ae Merge branch 'main' into add-release-channel-information-to-telemetry-events 2022-10-27 15:57:17 -04:00
Joseph T Lyons
93e1e30323 Add release channel information to telemetry events 2022-10-27 15:53:14 -04:00
Max Brunsfeld
9b69f9a3ff Merge pull request #1828 from zed-industries/following-scrollbar
Show scrollbar when scrolling while following
2022-10-27 12:46:14 -07:00
Max Brunsfeld
d5fbb59656 Show scrollbar when scrolling while following 2022-10-27 12:42:34 -07:00
Max Brunsfeld
7ba95d5d6c 🔥 stray dbg 2022-10-27 12:42:20 -07:00
Max Brunsfeld
d79aeba2c1 Avoid spurious log messages in development builds 2022-10-27 12:42:03 -07:00
K Simmons
672b445676 minor tweak to keymap code 2022-10-27 12:36:53 -07:00
K Simmons
e02199fa2a fixed binding fallback 2022-10-27 12:33:51 -07:00
Max Brunsfeld
9e55051811 Tweak version-bumping scripts 2022-10-27 12:10:09 -07:00
Max Brunsfeld
7db176a763 Remove stale docs folder 2022-10-27 12:08:55 -07:00
Nate Butler
92886236a2 Refine editor styles
- Update active line backgrounds and line numbers
- Add a higher contrast border between the dock and panes
2022-10-27 14:59:50 -04:00
Mikayla Maki
8d94de8eb2 WIP: Change to matches to vec 2022-10-27 11:27:26 -07:00
Max Brunsfeld
eaebec88c0 Merge pull request #1825 from zed-industries/update-notification-release-channel
Indicate release channel in auto-update notification
2022-10-27 11:00:16 -07:00
Max Brunsfeld
22fa6c07dd Indicate release channel in auto-update notification 2022-10-27 10:57:59 -07:00
Joseph T. Lyons
afe9ab9d8c Merge pull request #1824 from zed-industries/change-telemetry-event-field-name-to-app
Change telemetry event field name to app
2022-10-27 13:16:45 -04:00
Max Brunsfeld
16139cc6b6 Merge pull request #1822 from zed-industries/dont-bundle-app-on-prs
Don't bundle the app on CI for PRs
2022-10-27 10:10:29 -07:00
Joseph T Lyons
31a904d370 Change telemetry event field name to app 2022-10-27 12:35:35 -04:00
Max Brunsfeld
02cf7679a3 0.63.x dev 2022-10-26 23:04:36 -07:00
Max Brunsfeld
df708465d1 Ensure only the just-built app bundle is included in the DMG 2022-10-26 21:06:06 -07:00
Kay Simmons
aa9ccf3411 Merge pull request #1823 from zed-industries/reduce-cursor-blink-load
Reduce Cursor Blink CPU Load
2022-10-26 17:58:56 -07:00
Max Brunsfeld
6410fdc474 Clear out bundle directory before creating a new app bundle 2022-10-26 17:49:03 -07:00
Kay Simmons
499d947e69 Merge pull request #1821 from zed-industries/better-pending-bindings
Better pending bindings
2022-10-26 17:42:56 -07:00
K Simmons
c093516351 fix minor warning 2022-10-26 17:42:03 -07:00
K Simmons
41699224ff fix typo in blink manager disable which didn't properly disable, and start editors with the blink manager disabled 2022-10-26 17:39:17 -07:00
Max Brunsfeld
8886cb5786 Fix environment variable reference in bundle app job 2022-10-26 17:34:53 -07:00
Max Brunsfeld
d85d4de218 Don't bundle the app on CI for PRs
Just run that job on main and for release tags
2022-10-26 17:26:16 -07:00
Max Brunsfeld
f56f0b7bbb Fix error in bundle app CI job 2022-10-26 17:21:31 -07:00
K Simmons
ae79b50101 Disallow new keybindings when there are any pending 2022-10-26 16:57:23 -07:00
Max Brunsfeld
fcfc4a4298 Dev 0.62.0 2022-10-26 16:38:38 -07:00
Max Brunsfeld
d355bd3372 Merge pull request #1813 from zed-industries/preview-channel
Create preview channel
2022-10-26 16:34:14 -07:00
Max Brunsfeld
2bfd46d48c Fix setting of preview param in RPC URL 2022-10-26 16:19:19 -07:00
Max Brunsfeld
f1b41389b3 Allow overriding release channel at runtime via env var 2022-10-26 16:19:19 -07:00
Max Brunsfeld
92a4998ddc Check invariants before changing git state in railcar script 2022-10-26 16:19:19 -07:00
Max Brunsfeld
23d7209f82 Handle different app names in bundle script 2022-10-26 16:19:19 -07:00
Max Brunsfeld
cf3c610eba Add railcar script 2022-10-26 16:19:19 -07:00
Max Brunsfeld
6a010f58be Account for current release channel in bump-app-version script 2022-10-26 16:19:19 -07:00
Max Brunsfeld
0f1b0a4a78 Use a separate icon for preview releases 2022-10-26 16:19:19 -07:00
Max Brunsfeld
a4a8596a29 Store current release channel name in a file in the zed crate 2022-10-26 16:19:19 -07:00
Max Brunsfeld
1cdd3c0e28 Differentiate preview channel in 'about zed' dialog 2022-10-26 16:19:19 -07:00
Max Brunsfeld
22db5bffe8 Update DO SSL certificate id in kube manifest 2022-10-26 16:19:19 -07:00
Max Brunsfeld
a61f3b715b Create preview channel 2022-10-26 16:19:19 -07:00
K Simmons
949a28d49c wip 2022-10-26 15:57:42 -07:00
Kay Simmons
88be4fe77e Merge pull request #1804 from zed-industries/vim-go-to-line
fix jump to line number in vim mode
2022-10-26 11:43:27 -07:00
Julia
625a62626e Merge pull request #1820 from zed-industries/allow-mouse-move-through-dragged-item-receiver
Propagate mouse move event through dragged-item-receiver if not dragging
2022-10-26 12:22:30 -04:00
Julia
ee440cf300 Propagate mouse move event through dragged-item-receiver if not dragging 2022-10-26 12:06:32 -04:00
Antonio Scandurra
cf2ec99a4d Merge pull request #1819 from zed-industries/remote-renames
Assign a new language when remote buffer is renamed
2022-10-26 16:58:45 +01:00
Antonio Scandurra
bb0f6e85a8 Assign a new language when remote buffer is renamed 2022-10-26 17:52:39 +02:00
Antonio Scandurra
4412217f51 Merge pull request #1817 from zed-industries/show-notifications-on-all-screens
Show call notifications on all screens
2022-10-26 13:45:31 +01:00
Antonio Scandurra
1e85361914 Log instead of panicking when we can't retrieve a drawable 2022-10-26 14:30:48 +02:00
Antonio Scandurra
f611b443c0 Convert window frame rect to screen coordinates 2022-10-26 14:27:53 +02:00
Antonio Scandurra
5984be3d84 Display call notifications on all screens 2022-10-26 12:05:56 +02:00
Antonio Scandurra
5a8061ac7b Add the ability to open a window on a given screen
This is done by supplying the screen in the `WindowOptions` struct.
Note that it's optional, and we will let the operating system choose
which screen to show the window on when `screen` is not provided, as
we did before this change.
2022-10-26 12:04:45 +02:00
Antonio Scandurra
509c327b3b Merge pull request #1816 from zed-industries/letterbox-background
Use the same background color as the editor for `SharedScreen`
2022-10-26 10:37:15 +01:00
Antonio Scandurra
56a66b348d Use the same background color as the editor for SharedScreen 2022-10-26 08:33:32 +02:00
Joseph T. Lyons
a7d86a164c Merge pull request #1812 from zed-industries/fix-500-error-on-user-join
Fix duplicate key error that occurs when a user joins that is already in the db
2022-10-25 16:55:25 -04:00
Joseph T Lyons
383334633f Fix duplicate key error that occurs when a user joins that is already in the db
Co-Authored-By: Max Brunsfeld <maxbrunsfeld@gmail.com>
2022-10-25 16:09:36 -04:00
Max Brunsfeld
6a2dc444c6 Merge pull request #1802 from zed-industries/autoclose-with-same-start-and-end
Fix autoclose skipping when start and end are the same character
2022-10-25 12:33:04 -07:00
Max Brunsfeld
e9073310c4 Add test for autoclosing w/ matching start and end char 2022-10-25 12:22:19 -07:00
Antonio Scandurra
3b67602b13 Merge pull request #1810 from zed-industries/contacts-scroll-position
Maintain scroll position in contacts list
2022-10-25 19:43:37 +01:00
Antonio Scandurra
04477e9f97 Explicitly list cargo workspace members
This prevents build failures when there are stale subfolders under
`crates/`.
2022-10-25 19:31:58 +02:00
Antonio Scandurra
990c83eabd Embed live_kit_client's .gitignore into top-level .gitignore
Co-authored-by: Max Brunsfeld <max@zed.dev>
2022-10-25 18:54:34 +02:00
Antonio Scandurra
ddc71653ad Maintain scroll position in contacts list
Co-Authored-By: Max Brunsfeld <max@zed.dev>
2022-10-25 18:36:33 +02:00
Antonio Scandurra
e5e5cf1314 Merge pull request #1809 from zed-industries/contacts-popover-z-index
Prevent expanded dock from hiding contacts popover
2022-10-25 13:02:51 +01:00
Antonio Scandurra
f364a15d89 Prevent expanded dock from hiding contacts popover 2022-10-25 13:47:37 +02:00
Antonio Scandurra
2b4fd53202 Rename height to z-index 2022-10-25 13:47:12 +02:00
Antonio Scandurra
dfe2fd0386 Allow specifying a custom height for stacking contexts 2022-10-25 13:41:47 +02:00
Antonio Scandurra
2055f05b09 💄 2022-10-25 12:19:25 +02:00
Antonio Scandurra
33ebfc3f10 Rename depth to height when referring to stacking contexts 2022-10-25 12:18:23 +02:00
Antonio Scandurra
6a4f3aaa56 Create a SceneBuilder and sort stacking contexts when calling build 2022-10-25 12:16:09 +02:00
Antonio Scandurra
c1f7ac0d8c Merge pull request #1808 from zed-industries/fix-diagnostics-on-rust
Match progress token's prefix to detect disk-based diagnostic progress
2022-10-25 10:46:59 +01:00
Antonio Scandurra
19adfdf8bb Match progress token's prefix to detect disk-based diagnostic progress
The new version of rust-analyzer changed the disk-based diagnostic token
to `rust-analyzer/checkOnSave/0`. The trailing number could be different
from 0 when there are multiple Rust projects open using the same rust-analyzer
instance.

As such, with this commit we will perform a prefix match as opposed to a strict
equality check when detecting a disk-based diagnostics progress token.
2022-10-25 11:35:59 +02:00
Antonio Scandurra
af74d5409a Merge pull request #1806 from zed-industries/pending-state-when-calling
Show a `Calling` indicator right away when initiating a call
2022-10-25 10:10:44 +01:00
Antonio Scandurra
2a3773240d Show a Calling indicator right away when initiating a call 2022-10-25 11:05:57 +02:00
K Simmons
782676dc67 fix jump to line number in vim mode 2022-10-25 00:39:40 -07:00
Kay Simmons
68717d0fe8 Merge pull request #1792 from zed-industries/fn-modifier
Add fn modifier
2022-10-25 00:35:00 -07:00
Kay Simmons
8bd9577318 Merge pull request #1791 from zed-industries/drag-tabs-more-places
Drag tabs more places
2022-10-25 00:34:50 -07:00
K Simmons
2ac537393d fix failing test 2022-10-25 00:11:59 -07:00
K Simmons
82956b618a remove derive_more 2022-10-25 00:06:43 -07:00
K Simmons
a725ded95e Add fn modifier to modifier keys in gpui and refactor platform events to use a single modifiers struct 2022-10-24 23:50:39 -07:00
K Simmons
113b7f6f97 tweak drop target overlay color and make stack fully constraint children by the first child
's size
2022-10-24 23:47:43 -07:00
K Simmons
aed085b168 remove unnecessary Move branch in dispatch_events 2022-10-24 23:32:01 -07:00
K Simmons
345544646a remove more notify on moves 2022-10-24 23:32:01 -07:00
K Simmons
4520227e98 remove mouse position from render params 2022-10-24 23:32:01 -07:00
K Simmons
f5795ffc6f roll back mouse position in mouse_state struct in favor of using the dragged element position 2022-10-24 23:32:01 -07:00
K Simmons
8cde64d3f6 extract dragged item target 2022-10-24 23:32:00 -07:00
K Simmons
d7b8a189e4 fix issue where empty pane is created 2022-10-24 23:32:00 -07:00
K Simmons
cfde3e348c Add pane splitting by dragged item. Works, but the overlay doesn't clear quite right 2022-10-24 23:31:58 -07:00
K Simmons
70e2951e35 add mouse region handler bool for adding the handler above the child 2022-10-24 23:30:35 -07:00
Julia
ba35536664 Add action to move active item into the dock
Co-Authored-By: Kay Simmons <kay@zed.dev>
2022-10-24 23:30:35 -07:00
Julia
b9f9819637 Handle tab drag end on pane items to insert after active item
Co-Authored-By: Kay Simmons <kay@zed.dev>
2022-10-24 23:30:35 -07:00
Kay Simmons
076d353e84 Merge pull request #1803 from zed-industries/fix-vim-motion-panic
Add more explicit neovim testcase exemptions
2022-10-24 23:30:06 -07:00
K Simmons
64e9b9f893 remove mode after which is unused 2022-10-24 18:31:26 -07:00
K Simmons
21ad375b42 Fix panic in vim motion when not listed as exclusive and add features enum to capture why tests are ignored 2022-10-24 18:27:56 -07:00
Max Brunsfeld
cb9534eae0 Fix autoclose skipping when start and end are the same character 2022-10-24 17:46:06 -07:00
Max Brunsfeld
8b43368bf9 Checkout submodules on CI when publishing collab images 2022-10-24 17:13:20 -07:00
Max Brunsfeld
c96c8fd782 collab 0.2.0 2022-10-24 17:06:54 -07:00
Mikayla Maki
c295f943ba Merge pull request #1799 from zed-industries/fix-project-panel-notify
Fix project panel not showing files / folders
2022-10-24 13:28:26 -07:00
Mikayla Maki
e527474dd9 removed dev file 2022-10-24 13:20:45 -07:00
Mikayla Maki
73f267167f Delete generate-db.rs 2022-10-24 13:19:30 -07:00
Mikayla Maki
40290a9a42 Added notify call 2022-10-24 13:18:02 -07:00
Max Brunsfeld
bd35468d18 Merge pull request #1785 from zed-industries/auto-deploy-collab
Automatically build collab server docker images based on git tags
2022-10-24 12:07:35 -07:00
Max Brunsfeld
c80395fc18 Merge branch 'main' into auto-deploy-collab 2022-10-24 12:01:32 -07:00
Max Brunsfeld
95be2c6070 Add version bump scripts 2022-10-24 08:58:14 -07:00
Antonio Scandurra
fb7a92242b Merge pull request #1793 from zed-industries/screen-sharing
Introduce screen-sharing
2022-10-24 16:53:05 +01:00
Nathan Sobo
8c2ff69515 Render a tooltip on toggle screen sharing button
Co-Authored-By: Antonio Scandurra <antonio@zed.dev>
2022-10-24 09:44:05 -06:00
Antonio Scandurra
011085a93f Revert "Temporarily upload app bundle as CI artifact"
This reverts commit 2b5ac535b9.
2022-10-24 17:36:19 +02:00
Antonio Scandurra
dce21900a7 Bump protocol version
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-10-24 17:06:40 +02:00
Antonio Scandurra
2b5ac535b9 Temporarily upload app bundle as CI artifact
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-10-24 17:04:33 +02:00
Antonio Scandurra
484c8f7cbe Provide LiveKit environment variables on Kubernetes
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-10-24 17:03:18 +02:00
Antonio Scandurra
7e4d582d1e Replace Screen Sharing label with Screen
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-10-24 16:50:56 +02:00
Antonio Scandurra
50c4783333 Add test for screen-sharing 2022-10-24 15:17:25 +02:00
Antonio Scandurra
9860dbbbea Set location on ActiveCall even before there's a room
We will automatically call `Room::set_location` once a room has been
assigned.
2022-10-24 15:07:25 +02:00
Antonio Scandurra
874a3605f8 Init submodules on CI 2022-10-24 14:28:58 +02:00
Antonio Scandurra
088c5bac1f Remove stray log statement 2022-10-24 11:02:41 +02:00
Antonio Scandurra
e135b982c1 Focus shared screen item when clicking on it 2022-10-24 11:02:10 +02:00
Antonio Scandurra
a8bd234aa4 Simplify room events 2022-10-24 10:53:44 +02:00
Antonio Scandurra
f99d70500c Allow opening shared screen via the contacts popover 2022-10-24 10:47:47 +02:00
Antonio Scandurra
476020ae84 Show shared screen as a pane item 2022-10-24 10:04:08 +02:00
Max Brunsfeld
2f1ddc0d0f Improve deploy scripts 2022-10-21 15:50:14 -07:00
Nate Butler
ef5844bc79 Merge pull request #1783 from zed-industries/add-new-internal-themes
Add new internal themes
2022-10-21 18:31:02 -04:00
Max Brunsfeld
0c9ceb51e6 Add what-is-deployed-script 2022-10-21 14:28:55 -07:00
Max Brunsfeld
cedc0f64d5 Run migrations via a collab subcommand 2022-10-21 14:28:55 -07:00
Max Brunsfeld
9952f08cce Publish collab docker images on CI, deploy pre-built images 2022-10-21 14:24:43 -07:00
Max Brunsfeld
efa6745035 Add more paths to dockerignore 2022-10-21 14:24:43 -07:00
Joseph T. Lyons
4816a587c3 Merge pull request #1781 from zed-industries/switch-to-mixpanel
Switch to mixpanel
2022-10-21 15:26:08 -04:00
Nate Butler
6514eb5209 Make the assets/themes folder if it doesn't exist
- Also only run clearThemes if the folder exists

Co-Authored-By: Mikayla Maki <mikayla.c.maki@gmail.com>
2022-10-21 13:19:44 -04:00
Nate Butler
2a38c4938d Update gitignore because of macOS case sensitive weirdness
Co-Authored-By: Mikayla Maki <mikayla.c.maki@gmail.com>
2022-10-21 13:05:59 -04:00
Nate Butler
b015761131 WIP Re-case internal and experiment theme folders
Co-Authored-By: Mikayla Maki <mikayla.c.maki@gmail.com>
2022-10-21 13:04:24 -04:00
Nate Butler
99e6ecc466 Update Zenburn license 2022-10-21 13:03:54 -04:00
Antonio Scandurra
7e411ae098 Merge branch 'main' into screen-sharing
# Conflicts:
#	crates/collab/src/integration_tests.rs
#	crates/collab/src/main.rs
#	styles/src/styleTree/workspace.ts
2022-10-21 14:29:45 +02:00
Antonio Scandurra
1bbb7dd126 Leave Zed room when LiveKit room disconnects 2022-10-21 14:21:45 +02:00
Antonio Scandurra
78969d0938 Switch back to using the legacy screen capturing API
The new API is buggy and inconsistent, so I think we should move on
for now.
2022-10-21 11:54:52 +02:00
Antonio Scandurra
bac3dc1ccd Re-build live_kit_client when MACOSX_DEPLOYMENT_TARGET changes 2022-10-21 10:18:03 +02:00
Antonio Scandurra
ae44a38285 Remove unused LKDisplays API 2022-10-21 10:12:24 +02:00
Nathan Sobo
77b13b1356 Merge pull request #1788 from zed-industries/style
Apply a slight stylistic tweak
2022-10-20 18:43:50 -06:00
Nathan Sobo
2e97e2dbfd Apply a slight stylistic tweak 2022-10-20 18:38:27 -06:00
Kay Simmons
75ec5c3b1b Merge pull request #1784 from zed-industries/fix-keymap-panic
Fix panic in keymap parsing
2022-10-20 16:39:38 -07:00
K Simmons
3a456b09cb catch keymap string only modifiers and no key 2022-10-20 16:30:07 -07:00
Joseph T Lyons
022f70b1de Temporarily restore integration with Amplitude
This will be reverted later, once we fully switch to Mixpanel
2022-10-20 19:27:55 -04:00
Nate Butler
c1e23fc6d9 Update tokyo night meta 2022-10-20 18:22:34 -04:00
Nate Butler
a6e9d0d061 Merge branch 'main' into add-new-internal-themes 2022-10-20 18:19:21 -04:00
Nate Butler
b700ea84a5 Add metadata to all themes and organize
Co-Authored-By: gibusu <95764254+gibusu@users.noreply.github.com>
2022-10-20 17:08:09 -04:00
Nathan Sobo
0ef62fc334 Preserve symlinks in WebRTC.framework to avoid bundle signing failure 2022-10-20 14:37:04 -06:00
Nate Butler
c3900565b9 Fix a few incorrectly named themes
Co-Authored-By: gibusu <95764254+gibusu@users.noreply.github.com>
2022-10-20 16:28:08 -04:00
Nate Butler
a86756ed20 Update gruvbox to use manual accent ramps
Also updated it's neutral to contain more values sourced from the gruvbox repo

Co-Authored-By: gibusu <95764254+gibusu@users.noreply.github.com>
2022-10-20 16:25:54 -04:00
Nate Butler
e3ef6d35ab Add a range of new themes as internal themes for testing 2022-10-20 15:32:56 -04:00
Nate Butler
038670cc6f Add brush trees as a experimental theme 2022-10-20 15:32:40 -04:00
Nate Butler
5d87a04dc3 Remove old theme template 2022-10-20 15:32:20 -04:00
Nate Butler
fbfe8a2311 WIP Update theme metadata and add license information 2022-10-20 15:32:13 -04:00
Nate Butler
bd8509990a Rename One theme and update Zed default theme 2022-10-20 15:31:17 -04:00
Nathan Sobo
6bdb08ab9c Fix crash loading Swift symbol (I think associated with concurrency)
I add /usr/lib/swift as an rpath, which seems to fix the issue even though
there doesn't seem to be a relevant library at that location on my machine.

Based on my research, wondering if `-Wl,-weak-lswiftCompatibilityConcurrency`
is also required for this to work on older OSes, but holding back for now.
2022-10-20 13:18:53 -06:00
Antonio Scandurra
db8b8ef66b WIP 2022-10-20 20:17:54 +02:00
Joseph T Lyons
ac5d5e2451 Merge branch 'main' into switch-to-mixpanel 2022-10-20 13:53:39 -04:00
Max Brunsfeld
fad6cfef05 Merge pull request #1782 from zed-industries/idempotent-redemption
Return an optional response when creating users via invites
2022-10-20 10:46:50 -07:00
Nate Butler
c83cae60f6 Add Ayu to iternal themes 2022-10-20 13:28:50 -04:00
Antonio Scandurra
9b8e6cce02 WIP: Try using the new ScreenCaptureKit API when possible 2022-10-20 19:28:21 +02:00
Nathan Sobo
9858906463 Return an optional response when creating users via invites
If the user already exists, we return none. This will allow the web frontend
to avoid reporting a "join alpha" user event but also not error.

Co-Authored-By: Max Brunsfeld <max@zed.dev>
Co-Authored-By: Joseph Lyons <joseph@zed.dev>
2022-10-20 10:52:34 -06:00
Antonio Scandurra
be1dc01d9e Add 5s timeout to LiveKit API requests
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-10-20 18:01:47 +02:00
Antonio Scandurra
de24b4b4e8 Bump minimum macOS version to 10.15.7
This solves an issue with loading Swift libraries when running the
x86_64 binary.

Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-10-20 18:01:41 +02:00
Antonio Scandurra
629d3d473c Copy WebRTC into Zed.app/Contents/Frameworks when bundling the app 2022-10-20 15:38:54 +02:00
Antonio Scandurra
5dc82d3df8 Delete all live-kit rooms when server is shut down 2022-10-20 14:34:05 +02:00
Antonio Scandurra
76a1b81e45 Update live-kit to the latest version 2022-10-20 14:03:26 +02:00
Antonio Scandurra
99aa1219d2 Simplify renderer interface for live-kit-client 2022-10-20 09:51:55 +02:00
Nathan Sobo
69472f7823 Ensure we can send a second frame 2022-10-19 19:21:09 -06:00
Nathan Sobo
723fa83909 Use fake LiveKit server to test we can send frames when screen sharing 2022-10-19 19:14:55 -06:00
Joseph T Lyons
2f064d5ccc Remove debug prints 2022-10-19 17:30:00 -04:00
Nate Butler
ae9a0a99ea Add new internal themes 2022-10-19 17:02:23 -04:00
Kay Simmons
c2b9b08944 Merge pull request #1665 from zed-industries/elevations
Tracking PR: Elevations
2022-10-19 13:59:34 -07:00
K Simmons
2aa2e5af7a fix issue with text component and adjust layer selections some more 2022-10-19 13:45:00 -07:00
K Simmons
b7c439f4c4 Fixup some theme inconsistencies and incorrect layer selections 2022-10-19 13:39:46 -07:00
Max Brunsfeld
e6b29086a9 Merge pull request #1777 from zed-industries/impersonate-via-secret-token
Impersonate via secret token
2022-10-19 13:32:40 -07:00
Max Brunsfeld
83e4e26989 Allow setting ZED_SERVER_URL to URL of a collab server 2022-10-19 13:27:14 -07:00
K Simmons
caec9c1f45 fixed issue in testbench 2022-10-19 13:13:50 -07:00
K Simmons
e3809c267d flattened layers and elevations 2022-10-19 13:02:51 -07:00
Nate Butler
0d9eecd2ed WIP command palette changes 2022-10-19 14:55:22 -04:00
Joseph T Lyons
d7915840d0 Switch to Mixpanel analytics
Co-Authored-By: Max Brunsfeld <maxbrunsfeld@gmail.com>
2022-10-19 14:53:48 -04:00
Mikayla Maki
8098697847 Re-removed chat panel 2022-10-19 11:45:20 -07:00
Mikayla Maki
4c2f8406c7 Restored chat_panel, just in case 2022-10-19 11:42:29 -07:00
Nate Butler
e0a477265d Use lab color interpolation to improve the dark end of accent ramps 2022-10-19 14:35:09 -04:00
Nate Butler
364c3f2f00 Contrast rebalances 2022-10-19 13:03:58 -04:00
Nate Butler
75c79d60fe Improve contrast/scanability of constants 2022-10-19 13:03:34 -04:00
Nate Butler
5b2dd8e4d0 build-themes -> build to fix building themes on save 2022-10-19 13:03:09 -04:00
Nate Butler
9e8e227b46 Rebalance rose-pine-dawn 2022-10-19 13:02:34 -04:00
Julia
adf7578007 Merge pull request #1778 from zed-industries/trackpad-scroll-snap-lock
Lock trackpad scrolling in buffers to axis until broken free
2022-10-19 12:02:59 -04:00
Antonio Scandurra
b6e5aa3bb0 Use live_kit_client::TestServer in integration tests
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-10-19 16:35:34 +02:00
Antonio Scandurra
288c039929 Start on implementing a fake live-kit server 2022-10-19 14:58:50 +02:00
Antonio Scandurra
fb5c6493cf WIP: Start on a fake implementation of live-kit 2022-10-19 13:53:40 +02:00
Antonio Scandurra
3160d07b9c Model pending screen share in Room 2022-10-19 11:38:24 +02:00
Antonio Scandurra
e49fc9f4b1 Prevent Room from screen-sharing twice 2022-10-19 10:45:51 +02:00
Antonio Scandurra
ed6f482e68 Exercise unpublish_track in live_kit_client 2022-10-19 10:39:48 +02:00
Antonio Scandurra
773f569385 Add control to toggle screen-sharing 2022-10-19 10:19:20 +02:00
Antonio Scandurra
219793afcc Merge remote-tracking branch 'origin/main' into screen-sharing 2022-10-19 10:04:56 +02:00
Mikayla Maki
571636c526 Fixed cursor color being black 2022-10-18 22:26:14 -07:00
Julia
cbc15b6b58 Lock trackpad scrolling in buffers to axis until broken free 2022-10-19 01:00:13 -04:00
Max Brunsfeld
c410935c9c Allow impersonating users via the api token, bypassing oauth 2022-10-18 17:36:54 -07:00
K Simmons
79cf5dbd4b remove rocksdb 2022-10-18 17:21:15 -07:00
Kay Simmons
da5203011c Merge pull request #1773 from zed-industries/rusqlite
Swap to sqlite for client persistence
2022-10-18 16:11:54 -07:00
Mikayla Maki
84c7aa9cad Finished up initial sqlite implemention
Co-Authored-By: kay@zed.dev
2022-10-18 15:58:05 -07:00
Nathan Sobo
f8e5a08324 Merge pull request #1764 from zed-industries/gpui-events
Eliminate dispatch_event on Element trait
2022-10-18 15:24:13 -06:00
Max Brunsfeld
5e57a33df7 Store entire Config struct on collab AppState 2022-10-18 13:58:03 -07:00
Max Brunsfeld
38bdf7ad92 Remove unused env vars from collab k8s manifest 2022-10-18 13:58:03 -07:00
Max Brunsfeld
5447f63e9d Fix error in changes-since-last-release script on PRs with no body 2022-10-18 13:12:27 -07:00
Max Brunsfeld
50ba8bdc9b 0.61.0 2022-10-18 13:05:16 -07:00
Max Brunsfeld
6f279c0239 Merge pull request #1776 from zed-industries/tabbar-scroll
Scroll horizontal flex lists by whichever scroll delta dimension is g…
2022-10-18 13:04:28 -07:00
Max Brunsfeld
26ccd70e77 Scroll horizontal flex lists by whichever scroll delta dimension is greater 2022-10-18 12:59:04 -07:00
K Simmons
b0ddbeb0ad Merge branch 'main' into elevations 2022-10-18 12:47:15 -07:00
Julia
826eb113e7 Merge pull request #1775 from zed-industries/drag-on-context-menu-still-click
Don't allow drag event to fall through context menu
2022-10-18 15:24:38 -04:00
Julia
2661a9cc98 Don't allow drag event to fall through context menu 2022-10-18 15:00:49 -04:00
K Simmons
b06366ebb7 Get rusqlite more shippable 2022-10-18 11:43:18 -07:00
Antonio Scandurra
c7a629ba6b Merge pull request #1774 from zed-industries/stale-connections
Correctly handle disconnect when a different client for the same user is on a call
2022-10-18 18:37:43 +01:00
Antonio Scandurra
d155c11729 Fix client unit test by sending Hello in FakeServer 2022-10-18 19:33:38 +02:00
Antonio Scandurra
0c3c1e1f68 WIP 2022-10-18 19:30:45 +02:00
Antonio Scandurra
6c322dc835 Clear out incoming call when removing last connection for a user
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-10-18 19:15:14 +02:00
K Simmons
6019e4c37b remove items migration 2022-10-18 10:13:47 -07:00
K Simmons
9c8dd66b20 dont reference db items 2022-10-18 10:13:04 -07:00
Antonio Scandurra
0c0e8688ed Use PeerId in TestServer::disconnect_client
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-10-18 19:05:37 +02:00
Antonio Scandurra
6146923dbb WIP: Start on test to ensure incoming calls cancel upon recipient disconnection
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-10-18 18:45:50 +02:00
Antonio Scandurra
2c4f003897 Tell clients their peer id on connection in Hello message
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-10-18 18:42:55 +02:00
Antonio Scandurra
0491747eed Only leave room on connections that are associated with the active call
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-10-18 17:42:10 +02:00
Antonio Scandurra
29b9651ebd Use CFRelease instead of a custom LKRelease 2022-10-18 15:47:56 +02:00
Antonio Scandurra
48a1dd1588 Delete room when no participants are left 2022-10-18 14:59:12 +02:00
Antonio Scandurra
9cf39b1da6 Disconnect from live-kit Room on drop 2022-10-18 14:50:03 +02:00
Antonio Scandurra
47be340cac Fix invoking RemoveParticipant on live-kit server 2022-10-18 14:35:06 +02:00
Antonio Scandurra
bf98300547 Render remote participant's screen preserving aspect ratio 2022-10-18 14:16:19 +02:00
Antonio Scandurra
46635956f4 Emit Frame event when new frames are generated for a remote track 2022-10-18 12:18:49 +02:00
Antonio Scandurra
8c6de99159 Use participant identity and track sid everywhere 2022-10-18 12:05:59 +02:00
Nathan Sobo
a42a703b35 Pass tracks to Rust unretained
We always call CFRetain when constructing a track on the Rust side.
2022-10-17 23:56:41 -06:00
Nathan Sobo
59fab0bb2d WIP 2022-10-17 23:47:55 -06:00
Nathan Sobo
c73e2c2d0f Get test_app running without crashing 2022-10-17 23:38:43 -06:00
Nathan Sobo
8c1c98a0bf WIP 2022-10-17 23:25:04 -06:00
K Simmons
d99a074bc0 revert workspace changes 2022-10-17 17:05:08 -07:00
K Simmons
05b4b443d9 working items schema 2022-10-17 17:04:30 -07:00
Mikayla Maki
4b09f77950 WIP 2022-10-17 17:04:30 -07:00
Mikayla Maki
dbea3cf20c Converted to using rusqlite 2022-10-17 17:04:30 -07:00
K Simmons
aa8fa4a6d5 more wip 2022-10-17 17:04:29 -07:00
K Simmons
dbc03e2668 wip 2022-10-17 17:04:19 -07:00
Mikayla Maki
4ef69c8361 Merge pull request #1769 from zed-industries/breadcrumbs
Fix breadcrumbs
2022-10-17 17:02:56 -07:00
Mikayla Maki
895aeb033f Merge branch 'main' into breadcrumbs 2022-10-17 16:51:38 -07:00
Kay Simmons
e15cc376b0 Merge pull request #1763 from zed-industries/cursor-blink-setting
Adds the ability to disable cursor blinking and replicates cursor shape to collaborators
2022-10-17 16:51:20 -07:00
K Simmons
54428ca6f6 swap to using vercel to run the local zed.dev server 2022-10-17 16:49:34 -07:00
K Simmons
54cf6fa838 Pull blink functionality out of editor and into blink manager. Make blink manager subscribe to settings changes in order to start blinking properly when it is re-enabled.
Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
2022-10-17 16:20:51 -07:00
K Simmons
09a0b3eb55 increment protocol version 2022-10-17 16:20:51 -07:00
K Simmons
40c3e925ad Add cursor blink setting and replicate cursor shape to remote collaborators 2022-10-17 16:20:47 -07:00
Mikayla Maki
5ef5147780 Merge branch 'main' into gpui-events 2022-10-17 15:43:41 -07:00
Mikayla Maki
318b923bac Merge pull request #1765 from zed-industries/fix-terminal-hyperlinks
Open hyperlinks on up, not down, and disable them when dragging.
2022-10-17 15:41:40 -07:00
Mikayla Maki
93a30ea940 Removed breadcrumb scrollable 2022-10-17 15:29:51 -07:00
Mikayla Maki
5bb2edca8b Added absolute path info to remote worktrees (updated protocol version) 2022-10-17 15:27:46 -07:00
Mikayla Maki
1789dfb8b1 Fixed tests 2022-10-17 14:53:52 -07:00
Mikayla Maki
f473eadf2d Fixed failing test, now to make breadcrumbs scrollable... 2022-10-17 13:57:29 -07:00
Mikayla Maki
1f161b9aa1 Show full, absolute paths when displaying a local worktree 2022-10-17 13:35:45 -07:00
Mikayla Maki
354fefe61b Resovled behavioral inconsistency with how projects with multiple roots are handled 2022-10-17 13:08:05 -07:00
Mikayla Maki
19c98bb5ad fixed a bug where files outside of the project would show 'untitled' in the search bar 2022-10-17 12:58:48 -07:00
Julia
2149c17a0a Merge pull request #1768 from zed-industries/git-gutter-meets-code-folding
Git gutter meets code folding (and word wrap fixes)
2022-10-17 14:51:47 -04:00
Julia
1716aff969 Cleanup 2022-10-17 14:41:16 -04:00
Julia
2a5d7ea2de Inclusively check for hunk in fold range 2022-10-17 13:11:11 -04:00
Julia
be34c50c72 Deduplicate identical hunk layouts 2022-10-17 12:41:20 -04:00
Julia
50ae3e03f7 More concrete usage of display map to handle diff hunk gutter layout 2022-10-17 12:28:44 -04:00
Antonio Scandurra
499b8f5f55 WIP 2022-10-17 18:00:54 +02:00
Antonio Scandurra
81d83841ab WIP: Start integrating screen-sharing 2022-10-17 14:50:05 +02:00
Antonio Scandurra
cce00526b9 Remove participants from live-kit rooms when they leave zed rooms 2022-10-17 14:03:44 +02:00
Antonio Scandurra
c9225bb87c WIP: Start integrating with LiveKit when creating/joining rooms 2022-10-17 12:20:55 +02:00
Antonio Scandurra
75c339851f Add live_kit_server::api::Client::{create,delete}_room 2022-10-17 11:24:09 +02:00
Antonio Scandurra
e39c7c62e4 Update livekit_client 2022-10-17 10:48:09 +02:00
Antonio Scandurra
b6bb2985f5 Merge pull request #1767 from zed-industries/notify-on-auto-update
Notify `ActivityIndicator` when `AutoUpdater` changes
2022-10-17 09:10:57 +01:00
Antonio Scandurra
6bdbab2faf Notify ActivityIndicator when AutoUpdater changes
This fixes a bug that caused the status bar to not update when the
auto-update system changed its status.
2022-10-17 10:05:38 +02:00
Antonio Scandurra
f09d6b7b95 WIP 2022-10-17 09:59:16 +02:00
Nathan Sobo
19a2752674 WIP: Update token module to support server api 2022-10-17 09:59:16 +02:00
Antonio Scandurra
5d433b1666 WIP: start on live_kit_server 2022-10-17 09:59:16 +02:00
Antonio Scandurra
caeae38e3a Move live_kit to live_kit_client and add live_kit_server 2022-10-17 09:59:16 +02:00
Antonio Scandurra
c25acc155d Move ownership of MacOSDisplay to the rust side 2022-10-17 09:59:16 +02:00
Antonio Scandurra
4222f86537 Temporarily use legacy screen capture API 2022-10-17 09:59:16 +02:00
Nathan Sobo
9569323f93 WIP: Getting a big black window, then a crash 2022-10-17 09:59:16 +02:00
Nathan Sobo
0bbba90f30 Use ScreenCaptureKit-enabled LiveKit SDK and add display_sources function
Co-Authored-By: Antonio Scandurra <antonio@zed.dev>
2022-10-17 09:59:16 +02:00
Mikayla Maki
f1ff557a25 Rearranged mouse handling 2022-10-16 17:31:19 -07:00
Joseph T. Lyons
23d7143298 Merge pull request #1666 from zed-industries/settings-for-journal
Settings for journal
2022-10-16 19:55:27 -04:00
Nathan Sobo
12eab6551f Remove dispatch_event from Element trait 2022-10-16 13:08:25 -06:00
Nathan Sobo
d25c6b15a6 Move Terminal key down event handling from element to View::key_down method 2022-10-16 12:55:02 -06:00
Nathan Sobo
b9308ad80d Move handling of modifier changes to new View hook 2022-10-16 12:47:48 -06:00
Nathan Sobo
6e363e464c Start on view-level dispatch approach for keyboard events 2022-10-16 11:46:31 -06:00
Nathan Sobo
6e53deb1b2 Refine mouse event naming 2022-10-16 11:18:58 -06:00
Joseph T Lyons
0717c168d9 Derive Serialize on HourFormat 2022-10-16 12:51:48 -04:00
Joseph T Lyons
6d020a3ee9 Do not derive Default on JournalSettings 2022-10-16 12:51:34 -04:00
Joseph T Lyons
9a381c1803 Merge branch 'main' into settings-for-journal 2022-10-16 12:42:18 -04:00
Nathan Sobo
3e23d1f48d Merge pull request #1762 from zed-industries/less-click-and-hover-invalidation
Reduce unnecessary view invalidations related to mouse events
2022-10-16 10:23:54 -06:00
Nathan Sobo
1750fcf833 Merge pull request #1761 from zed-industries/mouse-region-view-invalidation
Remove unconditional invalidation when calling mouse region handlers
2022-10-14 18:31:23 -06:00
Nathan Sobo
646d344a11 Avoid re-rendering editor on mouse move
Only notify editor when clearing highlights if there were highlights to
begin with.

Co-Authored-By: Max Brunsfeld <max@zed.dev>
2022-10-14 18:27:55 -06:00
Nathan Sobo
bc03592912 Only invalidate parent view on click/hover if we read that state when rendering
Co-Authored-By: Max Brunsfeld <max@zed.dev>
2022-10-14 18:09:15 -06:00
Max Brunsfeld
a4b518ec72 Merge pull request #1760 from zed-industries/invite-unknown-platform
Include waitlist entries w/ unknown platform when summarizing and sending invites
2022-10-14 16:24:48 -07:00
Max Brunsfeld
b541ac313c Revert unnecessary logic for fetching invites' platform_unknown flag 2022-10-14 16:13:38 -07:00
Nathan Sobo
934474f87e Remove unconditional invalidation when calling mouse region handlers
We want invalidation to opt-in as much as possible.
If you want a view to re-render, you need to call `cx.notify`.
2022-10-14 17:06:46 -06:00
Max Brunsfeld
3a4e802093 Include waitlist entries w/ unknown platform when summarizing and sending invites 2022-10-14 15:20:23 -07:00
Julia
b3eb5f7cdf WIP
Co-Authored-By: Kay Simmons <kay@zed.dev>
2022-10-14 17:14:33 -04:00
Mikayla Maki
c21e0e916c Merge pull request #1759 from zed-industries/move-page-up-down
Move page up / down
2022-10-14 14:02:27 -07:00
Mikayla Maki
d301a215f7 Finished implementing vscode, emacs, and mac style pageup/down. Added keybindings ctrl-v, alt-v for emacs up/down and shift-pageup, shift-pagedown for vscode style. Also improved incorporated pageup/down into context menus 2022-10-14 13:52:30 -07:00
Max Brunsfeld
8044beffc7 v0.60.4 2022-10-14 12:44:22 -07:00
Max Brunsfeld
8df84e0341 Add MovePageUp and MovePageDown editor commands
Co-authored-by: Mikayla Maki <mikayla@zed.dev>
2022-10-14 12:36:46 -07:00
Max Brunsfeld
137a9cefbd Enable auto-scroll when moving cursors in Editor::handle_input
Co-authored-by: Mikayla Maki <mikayla@zed.dev>
2022-10-14 11:32:22 -07:00
Max Brunsfeld
55576f879b Merge pull request #1758 from zed-industries/editor-paint-panic
Consolidate calculation of editor's visible row range
2022-10-14 10:47:16 -07:00
Max Brunsfeld
78aee53411 Merge pull request #1757 from zed-industries/detect-unshare
Clear project's shared state upon every disconnection
2022-10-14 10:44:35 -07:00
Max Brunsfeld
864020463f Consolidate calculation of editor's visible row range
We think this will fix a panic that was occuring in `paint_highlighted_range`
due to an out-of-bounds read into the line layouts. We think doing essentially the same
calculation in two different ways with floating point numbers might have
caused a different end row to be calculated in 2 different code paths.

Co-authored-by: Nathan Sobo <nathan@zed.dev>
2022-10-14 10:37:44 -07:00
Max Brunsfeld
2d3d07d4d7 Clear project's shared state upon every disconnection
Co-authored-by: Nathan Sobo <nathan@zed.dev>
Co-authored-by: Antonio Scandurra <as-cii@zed.dev>
2022-10-14 10:17:59 -07:00
Max Brunsfeld
ad6f9b2499 0.60.3 2022-10-14 09:35:57 -07:00
Max Brunsfeld
330968434f Merge pull request #1756 from zed-industries/autoclose-wrong-closing-bracket
Avoid skipping over a different closing bracket in autoclose
2022-10-14 09:34:33 -07:00
Max Brunsfeld
4b12fb6b3b Avoid skipping over a different closing bracket in autoclose 2022-10-14 09:30:30 -07:00
Nathan Sobo
eef086f60f 0.60.2 2022-10-13 16:26:26 -06:00
Nathan Sobo
6ac0b81778 Merge pull request #1754 from zed-industries/fix-list-scroll
Pass the current view id when painting List's mouse region instead of 10
2022-10-13 16:24:55 -06:00
Nathan Sobo
8d82702da2 Pass the current view id value when painting List's mouse region
Previously, a dummy value was being passed. I think this slipped in accidentally.
2022-10-13 15:57:19 -06:00
Julia
dde3dfdbf6 Quick cut of using display point conversion to layout hunks
Co-Authored-By: Max Brunsfeld <max@zed.dev>
2022-10-13 16:34:34 -04:00
Julia
8d609959f1 Clean 2022-10-13 15:23:41 -04:00
Julia
16f854b636 Expand diff gutter indicator to cover all of a wrapped line 2022-10-13 14:05:57 -04:00
Julia
9c47325c25 Use correct range to get diff hunks in the presence of wrapped lines 2022-10-13 13:52:44 -04:00
Max Brunsfeld
cf499abf31 v0.60.1 2022-10-13 10:00:07 -07:00
Antonio Scandurra
86ddbc6d26 Merge pull request #1752 from zed-industries/allow-inviting-users-to-another-guest-project
Allow inviting users to a project that was shared by someone else
2022-10-13 17:58:22 +01:00
Antonio Scandurra
b8bc5a282e Allow inviting users to a project that was shared by someone else
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
Co-Authored-By: Max Brunsfeld <max@zed.dev>
2022-10-13 18:48:14 +02:00
Antonio Scandurra
f5db02a605 Merge pull request #1749 from zed-industries/child-view-panic
Prevent `ChildView` from retaining an otherwise dropped view
2022-10-13 15:45:53 +01:00
Antonio Scandurra
9ebd586350 Improve error message when rendering a child view for a dropped view
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-10-13 16:40:52 +02:00
Antonio Scandurra
1bec8087ee Add unit test for ChildView 2022-10-13 15:59:52 +02:00
Antonio Scandurra
a5a60eb854 Log view name alongside error in ChildView 2022-10-13 15:44:01 +02:00
Antonio Scandurra
edb61a9c8f Avoid panicking if child view points to a view that was not rendered 2022-10-13 15:11:57 +02:00
Antonio Scandurra
06dfb74663 Prevent ChildView from retaining an otherwise dropped view 2022-10-13 15:04:57 +02:00
Antonio Scandurra
26b03afa60 Merge pull request #1747 from zed-industries/fix-clangd-error
Fix error on clangd when `compile-commands.json` is present
2022-10-13 10:16:10 +01:00
Antonio Scandurra
c4680e66ff Fix error on clangd when compile-commands.json is present
The language server was failing because we were forgetting to provide
a `jsonrpc` field for responses to requests coming from the lsp.
2022-10-13 11:10:23 +02:00
Antonio Scandurra
06e9b8276f Merge pull request #1745 from zed-industries/contact-popover-focus
Fix some issues with contact popover focus
2022-10-13 08:37:14 +01:00
Antonio Scandurra
ad975da8bd Merge pull request #1746 from zed-industries/maintain-buffer-identity-across-renames
Preserve buffer identity when underlying entry temporarily disappears
2022-10-13 08:36:21 +01:00
Antonio Scandurra
37a0fd33c5 Use fake file system for buffer identity test 2022-10-13 09:33:55 +02:00
Antonio Scandurra
f28cc5ca0c Preserve buffer identity when underlying entry temporarily disappears 2022-10-13 09:10:10 +02:00
Antonio Scandurra
0a1aea6cb8 Add test to ensure buffer identity is kept across Project::rename 2022-10-13 08:17:35 +02:00
Julia
a6a7e85894 Misc fixes, still broken soft wrap 2022-10-13 02:02:29 -04:00
Julia
e75dcc853b Include deletion hunks in fold regardless of end 2022-10-13 00:42:53 -04:00
Max Brunsfeld
b5786cbf30 Dismiss contacts popover when clicking outside, even w/o focus change
Co-authored-by: Nathan Sobo <nathan@zed.dev>
2022-10-12 17:55:11 -07:00
Max Brunsfeld
513c02e67f Remove spurious focus of contact popover when opening it
Co-authored-by: Nathan Sobo <nathan@zed.dev>
2022-10-12 17:39:44 -07:00
Mikayla Maki
51c0a140c6 Merge pull request #1743 from zed-industries/new-settings-writing
Improved settings writing to be strongly typed and based on settings file content diffs
2022-10-12 17:18:48 -07:00
Mikayla Maki
e73270085b Fixed settings 2022-10-12 17:11:47 -07:00
Mikayla Maki
dd1320e6d1 Improved settings writing to be strongly typed and based on settings file content diffs
Co-Authored-By: kay@zed.dev
2022-10-12 17:05:23 -07:00
Kay Simmons
d42bf8eebe Merge pull request #1740 from zed-industries/fix-dock-focus-issues
Fix Dock infinite loop
2022-10-12 16:19:09 -07:00
K Simmons
2a1dbd6fb5 Update gpui focus test to match the new removal of intermediate focus filtering 2022-10-12 15:57:29 -07:00
Max Brunsfeld
9760eb0081 Merge pull request #1742 from zed-industries/deps-fixes
Re-export basic text types from text and language crates, remove unused deps from collab
2022-10-12 15:56:55 -07:00
Max Brunsfeld
6cdf4e98fc Re-export basic text types from text and language crates
Also avoid production dependencies on fs and rope in collab
2022-10-12 15:48:19 -07:00
K Simmons
2ff6ffff58 fix lock merge error 2022-10-12 15:39:04 -07:00
Kay Simmons
27a87c3d9e Merge branch 'main' into fix-dock-focus-issues 2022-10-12 15:18:28 -07:00
K Simmons
1d8717f4de Remove focus filtering from gpui so all focus events result in focus-in and focus-out calls
Remove pane focused event in favor of focus_in at the workspace level
Added is_child to ViewContext to determine if a given view is a child of the current view
Fix issue where dock would get in a infinite loop when activated after dragging an item out of it
Fix issue where the last focused view in an item was not correctly refocused when a pane is focused after switching active tabs

Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
2022-10-12 15:10:00 -07:00
Max Brunsfeld
fedec68d39 Update Dockerfiles to use Rust 1.64 2022-10-12 14:25:40 -07:00
Max Brunsfeld
490a608663 v0.60.0 2022-10-12 14:18:40 -07:00
Max Brunsfeld
94a5bbc0ab Merge pull request #1739 from zed-industries/collab-menu-key-binding
Allow toggling collaboration menu from the keyboard
2022-10-12 14:17:51 -07:00
Max Brunsfeld
89f05ada0b Allow toggling collaboration menu from the keyboard 2022-10-12 14:14:03 -07:00
Max Brunsfeld
3bb1f0097f Merge pull request #1738 from zed-industries/out-of-sync-diagnostics
Fix bugs that caused guests to see different diagnostics than host
2022-10-12 14:13:16 -07:00
Max Brunsfeld
69dcfbb423 Send guests DiskBasedDiagnosticsFinished messages when they join a project
Co-authored-by: Antonio Scandurra <antonio@zed.dev>
2022-10-12 13:49:09 -07:00
Julia
e744520d90 Correctly offset diff hunk layouts 2022-10-12 16:40:19 -04:00
Max Brunsfeld
3c3671a193 Avoid sending stale diagnostics after sharing a worktree
Co-authored-by: Antonio Scandurra <antonio@zed.dev>
2022-10-12 11:33:19 -07:00
Max Brunsfeld
cbf31e6d27 Merge pull request #1734 from zed-industries/fix-layout-crash
Fix rounding error in computing editor's row range during layout
2022-10-12 09:38:47 -07:00
Mikayla Maki
b3567a7240 Merge pull request #1736 from zed-industries/fix-terminal-bold
Fix a bug in how I parse alacritty's styles
2022-10-12 09:38:27 -07:00
Mikayla Maki
296656570e Merge pull request #1735 from zed-industries/rollback-dock-anchor-setting
Stops the dock anchor from being written to settings
2022-10-12 09:34:27 -07:00
Mikayla Maki
aac24938f5 Fix a bug in how I parse alacritty's styles 2022-10-12 09:34:17 -07:00
Mikayla Maki
47332f97c7 Stops the dock anchor from being written to settings 2022-10-12 09:28:55 -07:00
Max Brunsfeld
1179f8f7be Fix rounding error in computing editor's row range during layout
Co-authored-by: Nathan Sobo <nathan@zed.dev>
Co-authored-by: Antonio Scandurra <antonio@zed.dev>
2022-10-12 09:19:29 -07:00
Antonio Scandurra
bd146306c6 Merge pull request #1729 from zed-industries/connection-timeout
Introduce client-side timeout when trying to connect
2022-10-12 14:43:35 +01:00
Antonio Scandurra
c4dde0f4e2 💄 2022-10-12 15:35:28 +02:00
Antonio Scandurra
ec19f0f8e9 Remove unnecessary async from Peer::add_connection 2022-10-12 15:32:39 +02:00
Antonio Scandurra
cc56fa9ea6 Introduce client-side timeout when trying to connect 2022-10-12 15:32:30 +02:00
Antonio Scandurra
a19783919c Merge pull request #1728 from zed-industries/plain-text-leaks
Clear auto-indent requests if they couldn't be computed
2022-10-12 10:38:44 +01:00
Antonio Scandurra
83d3fad80d Clear auto-indent requests if they couldn't be computed 2022-10-12 10:53:44 +02:00
Antonio Scandurra
202950aa98 Merge pull request #1726 from zed-industries/rejoining-projects
Fix opening a buffer after leaving and joining the same project
2022-10-12 09:37:50 +01:00
Antonio Scandurra
9adbab5d99 Fix opening a buffer after leaving and joining the same project
This bug existed prior to #1700 and was caused by not clearing the
buffers that were already shared with a peer that left and opened
a project using the same connection. When such peer would re-join
the project and open a buffer that it had opened previously, the
host assumed the peer had already seen that buffer and wouldn't bother
sending it again.
2022-10-12 10:31:06 +02:00
Julia
a6910584b6 Something's happening, nothing correct, but something 2022-10-12 00:39:56 -04:00
Mikayla Maki
e24a69b838 Merge pull request #1723 from zed-industries/test-branch
Writing settings
2022-10-11 20:33:03 -07:00
Mikayla Maki
b1f64d9550 Updated new vim tests with new rope crate 2022-10-11 20:25:39 -07:00
Mikayla Maki
41590ef64b Merge branch 'main' into test-branch 2022-10-11 19:55:32 -07:00
Mikayla Maki
e7b6d1befe Added theme and dock anchor saving :D 2022-10-11 19:18:29 -07:00
Max Brunsfeld
76a86b7e5e Merge pull request #1721 from zed-industries/scrollbar-fix
Fix scrollbar's range of motion in large files
2022-10-11 19:14:49 -07:00
Max Brunsfeld
7eceff1d7b Impose min scrollbar height in a way that doesn't impede scrollbar's movement
Also, fix the editor's scroll max so that you can scroll to the last
display row.
2022-10-11 18:50:04 -07:00
Kay Simmons
81a3a22379 Merge pull request #1685 from zed-industries/vim-text-objects
Vim Text Objects and Numeric Repitions
2022-10-11 16:36:19 -07:00
K Simmons
d1f1eb9a29 Add count argument to motion functions and add ability to jump to a given line 2022-10-11 16:27:54 -07:00
Mikayla Maki
5487f99ac7 Moved settings_file.rs into settings crate. Should be ready to start now :D 2022-10-11 16:03:38 -07:00
Joseph T Lyons
bc2a6e429c Use tag_name for Discord release message 2022-10-11 18:31:17 -04:00
Mikayla Maki
0beb97547e Finished refactoring out fs and rope 2022-10-11 15:25:54 -07:00
Joseph T. Lyons
941f4097fe Add amplitude release (#1720)
Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
2022-10-11 18:25:36 -04:00
K Simmons
673041d1f5 working quote and bracket text objects 2022-10-11 15:17:29 -07:00
Nate Butler
6dfa34fcf8 Remove a few Zed default themes
Co-Authored-By: Kay Simmons <3323631+Kethku@users.noreply.github.com>
2022-10-11 17:40:45 -04:00
Nate Butler
b626ec3bf9 Use different dark and light ramps for cave
Co-Authored-By: Kay Simmons <3323631+Kethku@users.noreply.github.com>
2022-10-11 17:39:38 -04:00
Nate Butler
5708879b5a Style elevations & update styleTrees
Also rename `info` -> `accent`

Co-Authored-By: Kay Simmons <3323631+Kethku@users.noreply.github.com>
2022-10-11 17:38:28 -04:00
Max Brunsfeld
638e9f9477 Merge pull request #1715 from zed-industries/scrollbars
Add scrollbars
2022-10-11 13:34:15 -07:00
Max Brunsfeld
acc85ad03c Impose a minimum height on the scrollbar 2022-10-11 13:18:33 -07:00
Mikayla Maki
0a8e2f6bb0 Moved fs to it's own crate, build failing due to cyclic dependency on rope 2022-10-11 13:03:36 -07:00
Max Brunsfeld
9bdcd37f60 Merge pull request #1718 from zed-industries/dont-wait-for-project-upload
Proceed with share while project state uploads
2022-10-11 12:48:33 -07:00
Mikayla Maki
a833652077 Undid change to paths variables and cleaned up leftovers 2022-10-11 12:48:30 -07:00
Mikayla Maki
7ce758b343 Added notes from working with Nathan 2022-10-11 12:48:30 -07:00
Mikayla Maki
cc8ae45012 Added theme writing code, really bad race condition 2022-10-11 12:48:30 -07:00
Max Brunsfeld
65b8c512fe Allow opening other local projects via contacts list 2022-10-11 12:37:00 -07:00
Max Brunsfeld
0e695eaae8 Wait for project sharing to complete in LSP status integration test 2022-10-11 12:15:54 -07:00
Max Brunsfeld
1f0a9ce418 Proceed with share while project state uploads
Co-authored-by: Antonio Scandurra <as-cii@zed.dev>
2022-10-11 10:17:20 -07:00
Antonio Scandurra
a656047c15 Merge pull request #1700 from zed-industries/room
Introduce call-based collaboration
2022-10-11 17:40:44 +01:00
Antonio Scandurra
f26695ea8c 💄 2022-10-11 18:34:04 +02:00
Max Brunsfeld
f4306d977f Refresh scrollbar auto-hide setting when opening a new editor 2022-10-11 09:28:17 -07:00
Max Brunsfeld
d93e75bf5f Make scrollbars a little bit narrower 2022-10-11 09:26:31 -07:00
Max Brunsfeld
67a32de7d4 Hide the scrollbar track, not just the thumb 2022-10-11 09:26:19 -07:00
Antonio Scandurra
ba6c5441c0 Always show invite link in contacts popover 2022-10-11 18:22:00 +02:00
Max Brunsfeld
e2700ff8c6 Enable/disable scrollbar auto-hide based on OS setting 2022-10-11 09:13:34 -07:00
Antonio Scandurra
f83de0a91c Respect contacts popover size 2022-10-11 17:30:17 +02:00
Antonio Scandurra
4c07a0782b Allow active call to be optional on workspace
This prepares us for a future where the workspace is unaware of the
active call and doesn't require all tests to invoke `call::init`.
2022-10-11 17:27:37 +02:00
Antonio Scandurra
ee2587d3e5 Fix integration tests 2022-10-11 17:09:54 +02:00
Antonio Scandurra
45d118f96f Decide whether to clip to visible bounds on a per-element basis
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-10-11 17:05:13 +02:00
Antonio Scandurra
eb711cde53 Polish styling of contacts popover
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-10-11 16:52:20 +02:00
Antonio Scandurra
4504b36c8f Show a different message when participant is active on unshared project
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-10-11 15:24:31 +02:00
Antonio Scandurra
29c3b81a0a Show prompt when closing last window while there's an active call
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-10-11 14:52:47 +02:00
Antonio Scandurra
feb17c29ec Show participant projects in contacts popover 2022-10-11 12:23:15 +02:00
Antonio Scandurra
8e7f96cebc Update contacts when automatically canceling calls 2022-10-11 11:55:15 +02:00
Antonio Scandurra
0a306808da Dismiss project shared notifications when a project was unshared 2022-10-11 11:44:31 +02:00
Antonio Scandurra
1d4bdfc4a1 Cancel calls automatically when caller hangs up or disconnects 2022-10-11 11:28:27 +02:00
Antonio Scandurra
9ec62d4c1f Foreground app when accepting calls and project shares 2022-10-11 11:03:49 +02:00
Antonio Scandurra
bf0a04ab50 Dismiss popover when contact finder is unfocused 2022-10-11 11:01:38 +02:00
Antonio Scandurra
bf488f2027 Show project root names when displaying incoming call notification 2022-10-11 10:59:36 +02:00
Max Brunsfeld
b229bc69b9 Tweak scrollbar styling 2022-10-10 17:54:40 -07:00
Max Brunsfeld
7b084199be Auto-hide scrollbars 2022-10-10 17:54:29 -07:00
Nathan Sobo
e0b6b0df2a Rename Join button to Open, rework message slightly 2022-10-10 18:12:00 -06:00
Max Brunsfeld
6dcf638322 Represent scrollbar range with f32s 2022-10-10 17:06:48 -07:00
Nathan Sobo
b8c2acf0f2 Show worktree root names when sharing additional projects on a call
Co-Authored-By: Antonio Scandurra <antonio@zed.dev>
2022-10-10 17:56:03 -06:00
Max Brunsfeld
eedcc585af Add scrollbars to editors 2022-10-10 16:20:47 -07:00
Kay Simmons
7528bf8f32 Merge pull request #1714 from zed-industries/fix-autoclose
Don't autoclose brackets when `close` is false
2022-10-10 15:35:47 -07:00
K Simmons
0d31ea7cf2 fix minor issue where undo is not available in visual mode 2022-10-10 15:34:40 -07:00
K Simmons
6a237deb21 Add some tests for portions of visual text objects. Note: they are slightly broken currently as described in the tests 2022-10-10 15:32:12 -07:00
Nate Butler
95bc18a995 Fix color ramps to use colored fg 2022-10-10 17:50:41 -04:00
K Simmons
d2494822b0 Add assertion context manager to TestAppContext and convert existing vim tests to use neovim backed test context 2022-10-10 14:46:07 -07:00
Nate Butler
61dc703a58 Improve feedback button hover state 2022-10-10 17:42:23 -04:00
Nate Butler
a87d9d3578 Make code actions/autocomplete match contextMenu style 2022-10-10 17:35:12 -04:00
Nathan Sobo
425e540c9a Fix tests by providing close: true 2022-10-10 15:29:24 -06:00
Nathan Sobo
3ae96f2c6e Don't autoclose brackets when is false 2022-10-10 15:15:43 -06:00
Nate Butler
fc770c6ea5 Merge pull request #1713 from zed-industries/elevations-dynamic-layers
(Elevations) Dynamic StyleSets
2022-10-10 16:59:22 -04:00
Nate Butler
0c68abbe17 Revert tab bar to pre-elevation style 2022-10-10 16:53:38 -04:00
Mikayla Maki
576581c20d Merge pull request #1699 from zed-industries/page-up
Implemented page up and page down for the editor
2022-10-10 11:43:35 -07:00
Mikayla Maki
1d2495d57b Re-arrange how lines are set 2022-10-10 11:38:28 -07:00
Julia
7d6690335f Merge pull request #1712 from zed-industries/dont-select-on-copy-by-default-terminal
Don't select on copy by default in the terminal
2022-10-10 14:15:20 -04:00
Julia
2f96a09c46 Don't select on copy by default in the terminal
Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
2022-10-10 13:48:56 -04:00
Antonio Scandurra
94c68d246e 📝
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-10-10 19:18:05 +02:00
Antonio Scandurra
8dc99d42ff Remove menu bar extra 2022-10-10 18:21:11 +02:00
Antonio Scandurra
04fcd18c75 Show contacts popover when clicking on menu bar extra 2022-10-10 16:30:02 +02:00
Antonio Scandurra
d9d99e5e04 Fix seed script 2022-10-10 16:05:22 +02:00
Antonio Scandurra
5f9cedad23 Add margin to picker in contacts popover 2022-10-10 16:05:09 +02:00
Antonio Scandurra
afaacba41f Merge remote-tracking branch 'origin/main' into room 2022-10-10 15:43:38 +02:00
Antonio Scandurra
3396a98978 💄 2022-10-10 14:41:18 +02:00
Antonio Scandurra
7cfe435e62 Style project shared notifications 2022-10-10 14:37:51 +02:00
Antonio Scandurra
9d990ae329 Show all room participants in titlebar
...and allow following them into external projects.
2022-10-10 14:20:45 +02:00
Antonio Scandurra
25ff5959fb Superimpose external location message on active view 2022-10-10 12:23:50 +02:00
Antonio Scandurra
d7bac3cea6 Style incoming call notification 2022-10-10 11:36:39 +02:00
Antonio Scandurra
79748803a9 Add leave button on active call header 2022-10-10 10:30:51 +02:00
Antonio Scandurra
6f4edf6df5 Move contact finder into contacts popover 2022-10-10 09:56:21 +02:00
Mikayla Maki
1af4b263b2 Implemented page up and page down for the editor 2022-10-09 19:19:40 -07:00
Nate Butler
2d25e25ec3 WIP + Format 2022-10-09 19:43:06 -04:00
Nate Butler
c4028ef116 Calculate styles dynamically 2022-10-09 16:11:02 -04:00
Nate Butler
393d728769 wip 2022-10-09 15:27:39 -04:00
K Simmons
5fec8c8bfd Enable verifying of visual mode selections in neovim backed tests 2022-10-09 01:19:22 -07:00
K Simmons
f90b693ed5 fix some warnings and merge errors 2022-10-08 23:49:04 -07:00
K Simmons
515c1ea123 Fixed some neovim test context issues, added repeated commands in vim mode, and ported some tests to use the neovim testing strategy 2022-10-08 21:52:07 -07:00
K Simmons
b82db3a254 Adds word and sentence text objects along with a new vim testing system which uses cached neovim data to verify our test accuracy 2022-10-08 21:51:49 -07:00
Antonio Scandurra
34cb742db1 Set current location after calling another user 2022-10-08 14:47:40 +02:00
Antonio Scandurra
59aaf4ce1b Call contact on enter 2022-10-08 14:43:41 +02:00
Antonio Scandurra
d14744d02f Show current user in active call 2022-10-08 14:38:17 +02:00
Max Brunsfeld
e96abf1429 0.59.0 2022-10-07 14:51:18 -07:00
Mikayla Maki
2758234e03 Merge pull request #1693 from zed-industries/terminal-tidying
Terminal Tidying
2022-10-07 13:11:43 -07:00
Max Brunsfeld
00188511cb Merge pull request #1697 from zed-industries/css-highlighting-fixes
Highlighting fixes
2022-10-07 12:56:31 -07:00
Julia
4456e81163 Merge pull request #1696 from zed-industries/reset-diff-on-set-none-diff-base
Reset buffer git diff when setting diff base to None
2022-10-07 15:48:18 -04:00
Max Brunsfeld
6ecf870c66 Tweak SCREAMING_SNAKE_CASE regexes in highlight queries 2022-10-07 12:46:49 -07:00
Max Brunsfeld
95cb9ceac9 Collapse variant and type into the same color 2022-10-07 12:44:55 -07:00
Max Brunsfeld
fcf13b44fb CSS: color '#' the same as the rest of the color 2022-10-07 12:44:39 -07:00
Max Brunsfeld
070c4bc503 Add color for 'variable.special' and use it in highlight queries 2022-10-07 12:44:20 -07:00
Julia
e15f27106d Reset buffer git diff when setting diff base to None
Co-Authored-By: Joseph Lyons <joseph@zed.dev>
2022-10-07 15:37:37 -04:00
Mikayla Maki
15595a67fa Added a horrible hacky way of doing cmd-k correctly. 2022-10-07 12:04:26 -07:00
Mikayla Maki
bf50a8ad8e Implemented a simplistic version of correct cmd-k behavior 2022-10-07 11:37:39 -07:00
Mikayla Maki
188b775fa6 Fixed non-block terminal cursors being displayed incorrectly 2022-10-07 10:03:09 -07:00
Max Brunsfeld
ec76146a23 Merge pull request #1692 from zed-industries/avoid-duplicate-autoformat-edits
Avoid duplicate autoformat edits
2022-10-07 09:35:10 -07:00
Antonio Scandurra
f9fb3f78b2 WIP: Render active call in contacts popover
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-10-07 17:01:48 +02:00
Antonio Scandurra
96c5bb8c39 Fix flicker due to adding and removing menu bar extra unnecessarily 2022-10-07 15:07:09 +02:00
Antonio Scandurra
560d8a8004 Don't leave the room if there's a pending room update 2022-10-07 14:52:39 +02:00
Antonio Scandurra
251e06c50f 💄 2022-10-07 14:51:04 +02:00
Antonio Scandurra
6fb5901d69 Ensure sharing the same project twice is idempotent 2022-10-07 14:47:06 +02:00
Antonio Scandurra
d3cddfdced Fix styling for busy contacts 2022-10-07 14:42:18 +02:00
Antonio Scandurra
386de03f46 Fix room disconnection problems when creating room and sharing project 2022-10-07 14:39:11 +02:00
Antonio Scandurra
4aaf3df8c7 Show contact status 2022-10-07 13:56:28 +02:00
Antonio Scandurra
d7cea646fc Include a busy field in proto::Contact 2022-10-07 12:21:56 +02:00
Antonio Scandurra
e82320cde8 Never set a room on active call if it is offline 2022-10-07 12:00:23 +02:00
Antonio Scandurra
669406d5af Leave room when client is the only participant 2022-10-07 11:58:49 +02:00
Antonio Scandurra
b479c8c8ba Move project sharing into Room 2022-10-07 10:14:17 +02:00
Antonio Scandurra
3d467a9491 Unset room on active call when disconnecting 2022-10-07 09:23:25 +02:00
Julia
8fb8fff61b Merge pull request #1682 from zed-industries/load-diff-base-from-correct-relative-path
Fix some git gutter bugs
2022-10-06 22:28:52 -04:00
Julia
d67fad8dca Extend a test to cover repos not at worktree root 2022-10-06 22:20:10 -04:00
Nate Butler
431ac1267a Update contextMenu.ts 2022-10-06 21:08:53 -04:00
Max Brunsfeld
47a8e4222a Don't allow multiple concurrent formatting requests for the same buffer
Co-authored-by: Nathan Sobo <nathan@zed.dev>
2022-10-06 17:03:38 -07:00
Max Brunsfeld
4508d94a3e In deterministic executor, ensure fake timers are ordered by wake time
Previously, advancing the clock would fail to wake a timer that was
set *after* another time whose wake time had not yet arrived.
2022-10-06 17:03:23 -07:00
Max Brunsfeld
8411d886ac Fix multi-line string formatting in editor_test.rs 2022-10-06 15:13:29 -07:00
Max Brunsfeld
17ed80f74d Merge pull request #1691 from zed-industries/move-tests
Organize buffer and editor tests
2022-10-06 13:39:54 -07:00
Max Brunsfeld
63e1c839fe Rename language::tests -> language::buffer_tests 2022-10-06 13:32:49 -07:00
Max Brunsfeld
b6525e9164 Extract editor tests to their own file 2022-10-06 13:32:34 -07:00
Max Brunsfeld
c0ee8dc007 Merge pull request #1689 from zed-industries/optimize-buffer-diff
Apply buffer diff edits as a single batch
2022-10-06 12:28:42 -07:00
Max Brunsfeld
fe7a39ba5c Apply buffer diff edits as a single batch 2022-10-06 11:54:28 -07:00
Max Brunsfeld
51fa06cc8d Merge pull request #1404 from zed-industries/html-support
Basic html support
2022-10-06 10:32:44 -07:00
Julia
771215d254 Reload git index on file events to catch new contents 2022-10-06 12:01:21 -04:00
Antonio Scandurra
9f81699e01 WIP: start on menu bar extra 2022-10-06 16:10:45 +02:00
Antonio Scandurra
95e08edbb8 Always include room id in protos
This is redundant, but it futures-proof the ability to talk about
multiple rooms at any given time and feels safer in terms of race
conditions.
2022-10-06 15:20:49 +02:00
Antonio Scandurra
baf6097b49 Remove stale contacts panel reference 2022-10-06 15:17:02 +02:00
Antonio Scandurra
4cb306fbf3 Implement call cancellation 2022-10-06 15:12:27 +02:00
Antonio Scandurra
2e84fc6737 Delete rooms without pending users or participants 2022-10-06 14:20:40 +02:00
Antonio Scandurra
c43956d70a Move contacts panel styles into contacts popover 2022-10-06 14:07:21 +02:00
Antonio Scandurra
40163da679 Move contacts panel features into collab_ui 2022-10-06 14:00:14 +02:00
Antonio Scandurra
7763acbdd5 Move IncomingCall into call crate 2022-10-06 09:52:03 +02:00
Antonio Scandurra
55cc142319 Move incoming calls into ActiveCall 2022-10-06 09:50:26 +02:00
Joseph T. Lyons
edf4c3ec00 Add Discord webhook for published releases (#1684) 2022-10-05 21:22:53 -04:00
Max Brunsfeld
b7e115a6a1 Add a test for multi-language auto-indent 2022-10-05 17:59:31 -07:00
Max Brunsfeld
7fb5fe036a Derive indent size from the language at the cursor when auto-indenting 2022-10-05 17:07:35 -07:00
Max Brunsfeld
8b86781ad1 Remove last usages of MultiBufferSnapshot::language 2022-10-05 14:44:34 -07:00
Julia
3f4be5521c Load diff base from correct relative path 2022-10-05 16:04:55 -04:00
Max Brunsfeld
aa86806408 Finish generalizing ToggleComments to support block comments 2022-10-05 12:25:32 -07:00
Nate Butler
5bc074005c WIP 2022-10-05 12:40:38 -04:00
Antonio Scandurra
fa31c9659b Check room invariants in Store::check_invariants 2022-10-05 16:29:22 +02:00
Antonio Scandurra
5ef342f8c4 Enhance integration test to verify creating rooms while busy 2022-10-05 16:20:01 +02:00
Antonio Scandurra
5b811e4304 Add integration test verifying calls to busy users 2022-10-05 16:14:40 +02:00
Antonio Scandurra
183ca5da6f Allow following users into external projects 2022-10-05 15:32:55 +02:00
Antonio Scandurra
8f8843711f Move logic for joining project into a global action in collab_ui 2022-10-05 15:04:03 +02:00
Antonio Scandurra
383c21046f Set room location when active workspace changes 2022-10-05 15:03:40 +02:00
Antonio Scandurra
78e3370c1e Set room only after project has been shared to avoid flicker 2022-10-05 11:19:44 +02:00
Antonio Scandurra
84eebbe24a Always open project when added to a call via the + button 2022-10-05 11:01:28 +02:00
Antonio Scandurra
087760dba0 Use AppContext instead of MutableAppContext for ActiveCall::global 2022-10-05 10:51:51 +02:00
Max Brunsfeld
d9fb8c90d8 Start work on toggling block comments for HTML 2022-10-04 17:27:03 -07:00
Julia
836b536a90 Merge pull request #1632 from zed-industries/git-gutter
Tracking PR: Git gutter
2022-10-04 15:12:28 -04:00
Julia
2bd947d4d0 Use correct start row for hunk retrieval & correct paint offset
Co-Authored-By: Joseph Lyons <joseph@zed.dev>
2022-10-04 15:04:42 -04:00
Nate Butler
4a61b1011e Minor one dark improvements
Co-Authored-By: gibusu <95764254+gibusu@users.noreply.github.com>
2022-10-04 14:53:06 -04:00
Nate Butler
84847ff181 Remap theme ramp domains
Co-Authored-By: gibusu <95764254+gibusu@users.noreply.github.com>
2022-10-04 14:49:57 -04:00
Max Brunsfeld
b5d941b10c 0.58.0 2022-10-04 11:43:52 -07:00
Nate Butler
0bbc02e10d Add bottom padding and spacing between items to pickers
Co-Authored-By: gibusu <95764254+gibusu@users.noreply.github.com>
2022-10-04 13:55:01 -04:00
Antonio Scandurra
fceba6814f Automatically share project when creating the room
Co-Authored-By: Max Brunsfeld <max@zed.dev>
2022-10-04 19:25:48 +02:00
Nate Butler
0ed811b81b Update palettes 2022-10-04 13:16:11 -04:00
Nate Butler
ce2112df43 Update offline indicator 2022-10-04 12:36:31 -04:00
Antonio Scandurra
678b013da6 Don't show share button for remote projects
Co-Authored-By: Max Brunsfeld <max@zed.dev>
2022-10-04 18:35:54 +02:00
Antonio Scandurra
ebee2168fc Re-emit notifications and events from ActiveCall
This lets us only observe and subscribe to the active call without
needing to track the underlying `Room` if it changes, which implies
writing the same boilerplate over and over.
2022-10-04 18:15:56 +02:00
Antonio Scandurra
41240351d3 Simplify Collaborator to stop including the user
It can be retrieved from the `Room` and we're guaranteed to have
a room in order to have collaborators in a project.
2022-10-04 18:00:54 +02:00
Antonio Scandurra
debedaf004 Show notification when a new project is shared and allow joining it 2022-10-04 16:55:41 +02:00
Antonio Scandurra
57930cb88a Show Share button for unshared projects when inside of a room 2022-10-04 15:56:20 +02:00
Antonio Scandurra
de917c4678 Use a different style for inactive participants 2022-10-04 15:06:20 +02:00
Antonio Scandurra
456dde200c Implement Room::set_location 2022-10-04 11:46:01 +02:00
Max Brunsfeld
218ba81013 Fix autoclose error when cursor was at column 0 2022-10-03 17:44:18 -07:00
Mikayla Maki
499e95d16a Removed debugs, simplified settings 2022-10-03 17:43:05 -07:00
Mikayla Maki
6f7547d28f Fixed a couple bugs in tests and worktree path handling 2022-10-03 17:18:38 -07:00
Max Brunsfeld
c354b9b959 Add assertions to test for autoclose with embedded languages 2022-10-03 13:24:37 -07:00
Max Brunsfeld
841ba405f0 Merge pull request #1680 from zed-industries/telemetry-tweaks
Telemetry tweaks
2022-10-03 13:08:05 -07:00
Julia
6f6d72890a Once again respect user settings for git gutter
Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
2022-10-03 15:42:30 -04:00
Max Brunsfeld
f3d83631ef Remove unnecessary min_id_length option from amplitude requests 2022-10-03 12:13:27 -07:00
Julia
e6487de069 Rename head text to indicate that it's not always going to be from head
Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
2022-10-03 15:11:06 -04:00
Julia
a5c2f22bf7 Move git gutter settings out of editor settings
Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
2022-10-03 14:53:33 -04:00
Nate Butler
7080dc9c23 WIP 2022-10-03 14:08:01 -04:00
Max Brunsfeld
06813be5c8 Mark platform as "Zed" for telemetry events from the app
Co-authored-by: Joseph Lyons <joseph@zed.dev>
2022-10-03 11:05:45 -07:00
Julia
8f4b3c3493 Store repo content path as absolute
Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
2022-10-03 14:00:58 -04:00
Max Brunsfeld
4477f95ee6 Set staff user property in telemetry
Co-authored-by: Joseph Lyons <joseph@zed.dev>
2022-10-03 10:52:57 -07:00
Julia
9427bb7553 Be clearer about using GitFilesIncluded setting 2022-10-03 11:58:48 -04:00
Antonio Scandurra
1e45198b9f Emit event on Room when a user shares a new project 2022-10-03 17:12:07 +02:00
Antonio Scandurra
ad323d6e3b Automatically fetch remote participant users in Room 2022-10-03 16:09:49 +02:00
Antonio Scandurra
da6106db8e Prevent calls from users who aren't contacts 2022-10-03 15:54:20 +02:00
Antonio Scandurra
bec6b41448 Fix randomized integration test failure 2022-10-03 15:50:47 +02:00
Antonio Scandurra
6426037653 Adapt integration tests to always pass a room id to Project::share
Randomized test is failing, so we'll look into that next.
2022-10-03 15:44:11 +02:00
Mikayla Maki
01176e04b7 Added clarification for git gutter settings 2022-10-02 18:42:03 -07:00
Mikayla Maki
c237075102 Touched up settings text 2022-10-02 18:35:19 -07:00
Mikayla Maki
0f1d71c38f Merge branch 'main' into git-gutter 2022-10-02 18:03:50 -07:00
Mikayla Maki
56b4162023 Fix stray merge failure 2022-10-02 18:02:25 -07:00
Antonio Scandurra
fd42811ef1 Cache CGEventSource and avoid leaking CGEvent when handling events 2022-10-02 18:01:49 -07:00
Max Brunsfeld
34926abe83 0.57.0 2022-10-02 18:01:49 -07:00
Max Brunsfeld
1aa554f4c9 Fix FakeServer to expect new GetPrivateUserInfo request 2022-10-02 18:01:49 -07:00
Mikayla Maki
52dbf2f9b8 add proto stuff 2022-10-02 18:01:37 -07:00
Mikayla Maki
5769cdc354 made git diff rendering respect line wrap 2022-10-02 18:00:13 -07:00
Julia
7f84abaf13 Increment protocol version again for previous commit 2022-10-02 14:11:35 -04:00
Mikayla Maki
512f817e2f Added proto messages for updating the head text 2022-10-01 18:18:35 -07:00
Mikayla Maki
8c24c858c9 Touched up comments 2022-09-30 17:36:22 -07:00
Mikayla Maki
a1299d9b68 Fixed 1 test 2022-09-30 17:34:14 -07:00
Mikayla Maki
af0974264c Refactored git repository code to seperate out repository entry tracking data and git2 mocking code.
Co-authored-by: Max <max@zed.dev>
Co-authored-by: Julia <julia@zed.dev>
2022-09-30 17:33:34 -07:00
Julia
c95646a298 WIP Start refactoring separation of concerns for repo metadata
Co-Authored-By: Max Brunsfeld <max@zed.dev>
Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
2022-09-30 18:25:25 -04:00
Julia
42b7820dbb Perform git diff on remote buffer open 2022-09-30 18:05:09 -04:00
Julia
ce7f6dd082 Start a test for remote git data updating
Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
Co-Authored-By: Max Brunsfeld <max@zed.dev>
2022-09-30 15:51:32 -04:00
Julia
6540936970 Fix some panics in tests 2022-09-30 13:51:54 -04:00
Julia
1c5d15b85e Use sumtree instead of iterator linear search for diff hunks in range
Co-Authored-By: Max Brunsfeld <max@zed.dev>
Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
2022-09-30 13:32:54 -04:00
Antonio Scandurra
964a5d2db7 WIP: require sharing projects on a given Room 2022-09-30 18:21:47 +02:00
Julia
bce25918a0 Fix test build 2022-09-30 11:13:22 -04:00
Antonio Scandurra
074b8f18d1 Rip out project registration and use sharing/unsharing instead 2022-09-30 12:23:57 +02:00
Antonio Scandurra
be8990ea78 Remove project join requests 2022-09-30 11:35:50 +02:00
Antonio Scandurra
761ae3ae6f Merge pull request #1673 from zed-industries/fix-cgevent-memory-leak
Cache `CGEventSource` and avoid leaking `CGEvent` when handling events
2022-09-30 09:04:25 +01:00
Antonio Scandurra
25bba396ef Cache CGEventSource and avoid leaking CGEvent when handling events 2022-09-30 09:51:03 +02:00
Joseph T Lyons
3c62de34f7 Change journal location setting name to "path" and default to ~ 2022-09-29 17:12:57 -04:00
Antonio Scandurra
b35e8f0164 Remove projects from contact updates
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-09-29 19:40:36 +02:00
Nate Butler
a6cccf82f7 Fix illegible rename text 2022-09-29 13:28:31 -04:00
Julia
fcf11b1181 Bump protocol version to be ahead of main 2022-09-29 13:16:02 -04:00
Julia
e865b85d9c Track index instead of head for diffs 2022-09-29 13:16:02 -04:00
Mikayla Maki
9fe6a5e83e made git stuff slightly more themable 2022-09-29 13:16:02 -04:00
Nate Butler
b395fbb3f2 wip 2022-09-29 13:16:02 -04:00
Nate Butler
8a2430090b WIP Git gutter styling 2022-09-29 13:16:02 -04:00
Mikayla Maki
113d3b88d0 Added test, and fix, for changed_repos method on LocalWorktree 2022-09-29 13:16:02 -04:00
Julia
f7714a25d1 Don't pretend this is async 2022-09-29 13:16:02 -04:00
Mikayla Maki
71b2126eca WIP, re-doing fs and fake git repos 2022-09-29 13:16:02 -04:00
Julia
d5fd531743 Move git related things into specialized git crate
Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
2022-09-29 13:16:02 -04:00
Julia
bf3b3da6ed Build again 2022-09-29 13:16:02 -04:00
Julia
7e5d49487b WIP Notifying buffers of head text change
Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
2022-09-29 13:16:02 -04:00
Julia
759b7f1e07 Update repo scan id when files under dot git dir events
Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
2022-09-29 13:16:02 -04:00
Julia
d2b18790a0 Remove git repos from worktree when deleted on storage
Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
2022-09-29 13:16:02 -04:00
Julia
4251e0f5f1 Find repos under worktree & return correct results for repo queries
Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
2022-09-29 13:16:02 -04:00
Mikayla Maki
c8e63d76a4 Get the test to failing,,, correctly 2022-09-29 13:16:02 -04:00
Mikayla Maki
6ac9308a03 Added git repository type infrastructure and moved git file system stuff into fs abstraction so we can test without touching the file system. Co-Authored-By: kay@zed.dev 2022-09-29 13:16:02 -04:00
Mikayla Maki
0d1b2a7e46 WIP - max & mikayla working on tests 2022-09-29 13:16:02 -04:00
Julia
bb8798a844 WIP pls amend me
Co-Authored-By: Max Brunsfeld <max@zed.dev>
Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
2022-09-29 13:16:02 -04:00
Julia
8d2de1074b Pull git indicator colors out of theme
Co-Authored-By: Kay Simmons <kay@zed.dev>
Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
2022-09-29 13:16:02 -04:00
Julia
632f47930f Utilize initial file contents as head text by default
Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
2022-09-29 13:16:02 -04:00
Julia
a679557e40 Avoid racing git diffs & allow for "as fast as possible" diff updating
Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
2022-09-29 13:16:02 -04:00
Julia
b18dd8fcff Fully qualify outside git-related code when a diff is a git diff 2022-09-29 13:16:02 -04:00
Julia
8edee9b2a8 Async-ify head text loading 2022-09-29 13:16:02 -04:00
Julia
6633c0b328 Perform initial file load git diff async 2022-09-29 13:16:02 -04:00
Julia
6825b6077a Properly invalidate when async git diff completes 2022-09-29 13:16:02 -04:00
Julia
9c82954877 Changed diffs to be async and dropped git delay 2022-09-29 13:16:02 -04:00
Julia
c4da8c46f7 Disable unnecessary libgit2 cargo features
Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
2022-09-29 13:16:02 -04:00
Julia
b9d84df127 Track buffer row divergence while iterating through diff lines
This allows for offsetting head row index of deleted lines to normalize
into buffer row space
2022-09-29 13:16:02 -04:00
Julia
446bf88655 Use row range while building buffer range during diff line iteration 2022-09-29 13:16:02 -04:00
Julia
03b6f3e0bf Reorganize for for purely file level invalidation 2022-09-29 13:16:02 -04:00
Julia
e72e132ce2 Clear out commented code & once again perform full file diff on update 2022-09-29 13:16:02 -04:00
Julia
c1249a3d84 Handle deletions more robustly and correctly 2022-09-29 13:16:02 -04:00
Julia
96917a8007 Small clean 2022-09-29 13:16:02 -04:00
Julia
2f7283fd13 buffer_divergence doesn't seem to be a concept that needs to be tracked 2022-09-29 13:16:02 -04:00
Julia
e0ea932fa7 Checkpoint preparing for a more organized approach to incremental diff 2022-09-29 13:16:02 -04:00
Julia
4b2040a7ca Move diff logic back into BufferDiff::update 2022-09-29 13:16:02 -04:00
Julia
a2e8fc79d9 Switch head range from row range to byte offset range
Co-Authored-By: Max Brunsfeld <max@zed.dev>
2022-09-29 13:16:02 -04:00
Julia
61ff24edc8 Move cloneable diff state into new snapshot type
Co-Authored-By: Max Brunsfeld <max@zed.dev>
2022-09-29 13:16:02 -04:00
Julia
a86e93d46f Checkpoint on incremental diff sumtree shenanigans 2022-09-29 13:16:02 -04:00
Julia
883d5b7a08 Update git gutter status after debounced delay
Co-authored-by: Max Brunsfeld <max@zed.com>
2022-09-29 13:16:02 -04:00
Julia
5157c71fa9 Render deletion gutter markers 2022-09-29 13:16:02 -04:00
Julia
fdda2abb78 Correct start/end of git diff hunks 2022-09-29 13:16:02 -04:00
Julia
641daf0a6e Correct git gutter indicator scroll position & add rounded corner 2022-09-29 13:16:02 -04:00
Julia
55ca02351c Start painting some sort of hunk info, it's wrong but it's close
Co-Authored-By: Max Brunsfeld <max@zed.dev>
2022-09-29 13:16:01 -04:00
Julia
6fa2e62fa4 Start asking Editors to update git after a debounced delay 2022-09-29 13:16:01 -04:00
ForLoveOfCats
2a14af4cde Load a file's head text on file load just to get started 2022-09-29 13:16:01 -04:00
Antonio Scandurra
1898e813f5 Encapsulate Room interaction within ActiveCall
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-09-29 17:39:53 +02:00
Antonio Scandurra
e0db62173a Rename room crate to call
Also, rename `client::Call` to `client::IncomingCall`.

Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-09-29 17:24:31 +02:00
Antonio Scandurra
1158911560 Wire up accepting/declining a call 2022-09-29 15:33:33 +02:00
Antonio Scandurra
634f9de7e6 Avoid using global for Room and extract that logic into ActiveCall 2022-09-29 10:48:51 +02:00
Joseph T Lyons
f8da5ab2e7 Remove "get" prefix from function names 2022-09-28 17:07:11 -04:00
Joseph T Lyons
fbe5f9225c Add descriptions to journal settings 2022-09-28 16:52:15 -04:00
Max Brunsfeld
4f44375abd Make Buffer::language_at fall back to Buffer::language
For languages with no grammar (plain text), there
will be no layers.
2022-09-28 13:38:54 -07:00
Joseph T Lyons
773423fcf4 Initial work to add settings to journal feature 2022-09-28 16:25:37 -04:00
Nate Butler
a62e2a38d7 Update projectPanel.ts 2022-09-28 16:04:15 -04:00
Nate Butler
48dcc465f2 WIP 2022-09-28 16:03:00 -04:00
Nate Butler
d0c50b4fbf Style tab bar 2022-09-28 15:53:06 -04:00
Max Brunsfeld
2da32af340 Update EditorTestContext usage to reflect new synchronous constructor 2022-09-28 12:36:55 -07:00
Max Brunsfeld
2b0794f5ae Restructure autoclosing to account for multi-language documents 2022-09-28 12:32:04 -07:00
Max Brunsfeld
67e188a015 Add Buffer::language_at, update MultiBuffer to use it
Co-authored-by: Julia Risley <floc@unpromptedtirade.com>
2022-09-28 12:32:04 -07:00
Max Brunsfeld
a2e57e8d71 Add basic syntax highlighting for CSS 2022-09-28 12:32:04 -07:00
Max Brunsfeld
21fb2b9bf1 Tweak HTML indents and highlights 2022-09-28 12:32:04 -07:00
Max Brunsfeld
e4f5e85c3c Add JavaScript language injection in HTML 2022-09-28 12:32:04 -07:00
Isaac Clayton
a48995c782 Basic html highlighting + lsp support 2022-09-28 12:32:04 -07:00
Antonio Scandurra
04d194924e WIP: Start on ActiveCall
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-09-28 19:50:13 +02:00
Antonio Scandurra
46b61feb9a Open popup window when receiving a call
We still need to style and allow people to accept the call but this
is a good starting point.

Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-09-28 19:35:24 +02:00
Antonio Scandurra
aa3cb8e35e Rename collab_titlebar_item crate to collab_ui
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-09-28 19:14:31 +02:00
Nathan Sobo
8ff4f044b7 Start a call when clicking on a contact in the contacts popover
Co-Authored-By: Antonio Scandurra <antonio@zed.dev>
2022-09-28 11:02:26 -06:00
Nate Butler
ab3a6f775e WIP Titlebar styling 2022-09-28 13:01:12 -04:00
Nathan Sobo
815cf44647 Rename AddParticipantPopover to ContactsPopover
Co-Authored-By: Antonio Scandurra <antonio@zed.dev>
2022-09-28 09:10:01 -06:00
Nathan Sobo
f5b2d56efd Remove contacts menu bar extra
Co-Authored-By: Antonio Scandurra <antonio@zed.dev>
2022-09-28 09:06:28 -06:00
Antonio Scandurra
1d1bd3975a Remove current user from contacts
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
2022-09-28 11:33:38 +02:00
Antonio Scandurra
4b73239972 WIP: Start moving contacts panel into "add participants" popover 2022-09-28 11:33:38 +02:00
Antonio Scandurra
0a29e13d4a Add active style when participant popover is open 2022-09-28 11:33:38 +02:00
Antonio Scandurra
0db6eb2fb8 Show add participant popover on click 2022-09-28 11:33:38 +02:00
Antonio Scandurra
782309f369 Rename contacts_titlebar_item to collab_titlebar_item 2022-09-28 11:33:38 +02:00
Antonio Scandurra
5a3a85b2c8 Introduce a + button in the titlebar 2022-09-28 11:33:38 +02:00
Antonio Scandurra
c8a48e8990 Extract contacts titlebar item into a separate crate
This allows us to implement a new contacts popover that uses the
`editor` crate.
2022-09-28 11:33:38 +02:00
Antonio Scandurra
80ab144bf3 Ring users upon connection if somebody was calling them before connecting
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-09-28 11:33:38 +02:00
Antonio Scandurra
6aa0f0b200 Leave room automatically on disconnection
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-09-28 11:33:38 +02:00
Antonio Scandurra
f0c45cbceb Remove projects from basic calls test for now 2022-09-28 11:33:38 +02:00
Antonio Scandurra
e55e7e4844 Leave room when Room entity is dropped 2022-09-28 11:33:38 +02:00
Antonio Scandurra
573086eed2 Always rely on the server to cancel the incoming call 2022-09-28 11:33:38 +02:00
Antonio Scandurra
df285def59 💄 2022-09-28 11:33:38 +02:00
Antonio Scandurra
bb9ce86a29 Introduce the ability of declining calls 2022-09-28 11:33:38 +02:00
Antonio Scandurra
f4697ff4d1 Prevent the same user from being called more than once 2022-09-28 11:33:38 +02:00
Antonio Scandurra
55b095cbd3 Implement joining a room and sending updates after people join/leave 2022-09-28 11:33:38 +02:00
Antonio Scandurra
4a9bf8f4fe Introduce call infrastructure
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-09-28 11:33:38 +02:00
Antonio Scandurra
ebb5ffcedc Introduce the ability of creating rooms on the server 2022-09-28 11:33:38 +02:00
Antonio Scandurra
0b1e372d11 Start sketching out an integration test for calls
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
2022-09-28 11:33:38 +02:00
Antonio Scandurra
8fec7da799 WIP 2022-09-28 11:33:38 +02:00
Antonio Scandurra
46019f8537 WIP 2022-09-28 11:33:38 +02:00
Nate Butler
0674ca14d9 Update the neutral ramp for Andromeda 2022-09-27 12:49:51 -04:00
Nate Butler
d0b35b5e19 WIP Update style trees 2022-09-26 22:51:00 -04:00
Nate Butler
01570504ad WIP Allow applying domains to theme ramps
Co-Authored-By: Kay Simmons <3323631+Kethku@users.noreply.github.com>
2022-09-26 17:41:59 -04:00
Nate Butler
506c28d2b6 Fix incorrect import 2022-09-26 15:39:21 -04:00
Nate Butler
53f58f72f2 Add zed-pro as an internal theme 2022-09-26 15:15:35 -04:00
Nate Butler
c9786fe464 Create a baseline for ramps to start tweaking from 2022-09-26 15:07:24 -04:00
Nate Butler
c2ffc7086c Minor styletree fixes 2022-09-26 15:07:11 -04:00
K Simmons
96f9ee784d add more states to the theme testbench 2022-09-22 14:25:15 -07:00
K Simmons
962f087ac2 promote variant to its own styleset 2022-09-22 13:29:19 -07:00
Nate Butler
ebe8c952e4 WIP work on bottom and middle layer sets 2022-09-22 12:08:53 -04:00
K Simmons
eabd687cbc More tweaks and add variant to theme testbench 2022-09-21 16:59:33 -07:00
K Simmons
593c7a8cd1 fix rebase error 2022-09-21 16:35:24 -07:00
K Simmons
79b9420017 minor tweaks 2022-09-21 16:32:44 -07:00
K Simmons
db5c83eb36 add theme testbench command 2022-09-21 16:32:44 -07:00
K Simmons
56f9543a95 reworked style tree to use colorScheme instead of old theme. Very limited style for now 2022-09-21 16:32:42 -07:00
518 changed files with 34853 additions and 21478 deletions

View File

@@ -1,3 +1,11 @@
/target
/manifest.yml
/migrate.yml
**/target
zed.xcworkspace
.DS_Store
plugins/bin
script/node_modules
styles/node_modules
crates/collab/static/styles.css
vendor/bin
assets/themes/*.json
assets/themes/internal/*.json
assets/themes/experiments/*.json

View File

@@ -4,6 +4,7 @@ on:
push:
branches:
- main
- "v*"
tags:
- "v*"
pull_request:
@@ -39,6 +40,7 @@ jobs:
uses: actions/checkout@v2
with:
clean: false
submodules: 'recursive'
- name: Run tests
run: cargo test --workspace --no-fail-fast
@@ -51,12 +53,14 @@ jobs:
runs-on:
- self-hosted
- bundle
if: ${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v') }}
needs: tests
env:
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
APPLE_NOTARIZATION_USERNAME: ${{ secrets.APPLE_NOTARIZATION_USERNAME }}
APPLE_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }}
ZED_AMPLITUDE_API_KEY: ${{ secrets.ZED_AMPLITUDE_API_KEY }}
ZED_MIXPANEL_TOKEN: ${{ secrets.ZED_MIXPANEL_TOKEN }}
steps:
- name: Install Rust
run: |
@@ -75,10 +79,32 @@ jobs:
uses: actions/checkout@v2
with:
clean: false
submodules: 'recursive'
- name: Validate version
- name: Determine version and release channel
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
run: script/validate-version
run: |
set -eu
version=$(script/get-crate-version zed)
channel=$(cat crates/zed/RELEASE_CHANNEL)
echo "Publishing version: ${version} on release channel ${channel}"
echo "RELEASE_CHANNEL=${channel}" >> $GITHUB_ENV
expected_tag_name=""
case ${channel} in
stable)
expected_tag_name="v${version}";;
preview)
expected_tag_name="v${version}-pre";;
*)
echo "can't publish a release on channel ${channel}"
exit 1;;
esac
if [[ $GITHUB_REF_NAME != $expected_tag_name ]]; then
echo "invalid release tag ${GITHUB_REF_NAME}. expected ${expected_tag_name}"
exit 1
fi
- name: Create app bundle
run: script/bundle
@@ -91,12 +117,12 @@ jobs:
path: target/release/Zed.dmg
- uses: softprops/action-gh-release@v1
name: Upload app bundle to release if release tag
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
name: Upload app bundle to release
if: ${{ env.RELEASE_CHANNEL }}
with:
draft: true
prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
files: target/release/Zed.dmg
overwrite: true
body: ""
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -0,0 +1,46 @@
name: Publish Collab Server Image
on:
push:
tags:
- collab-v*
env:
DOCKER_BUILDKIT: 1
DIGITALOCEAN_ACCESS_TOKEN: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
jobs:
publish:
name: Publish collab server image
runs-on:
- self-hosted
- deploy
steps:
- name: Add Rust to the PATH
run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH
- name: Sign into DigitalOcean docker registry
run: doctl registry login
- name: Checkout repo
uses: actions/checkout@v3
with:
clean: false
submodules: 'recursive'
- name: Determine version
run: |
set -eu
version=$(script/get-crate-version collab)
if [[ $GITHUB_REF_NAME != "collab-v${version}" ]]; then
echo "release tag ${GITHUB_REF_NAME} does not match version ${version}"
exit 1
fi
echo "Publishing collab version: ${version}"
echo "COLLAB_VERSION=${version}" >> $GITHUB_ENV
- name: Build docker image
run: docker build . --tag registry.digitalocean.com/zed/collab:v${COLLAB_VERSION}
- name: Publish docker image
run: docker push registry.digitalocean.com/zed/collab:v${COLLAB_VERSION}

39
.github/workflows/release_actions.yml vendored Normal file
View File

@@ -0,0 +1,39 @@
on:
release:
types: [published]
jobs:
discord_release:
runs-on: ubuntu-latest
steps:
- name: Discord Webhook Action
uses: tsickert/discord-webhook@v5.3.0
if: ${{ ! github.event.release.prerelease }}
with:
webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
content: |
📣 Zed ${{ github.event.release.tag_name }} was just released!
Restart your Zed or head to https://zed.dev/releases to grab it.
```md
### Changelog
${{ github.event.release.body }}
```
mixpanel_release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: "3.10.5"
architecture: "x64"
cache: "pip"
- run: pip install -r script/mixpanel_release/requirements.txt
- run: >
python script/mixpanel_release/main.py
${{ github.event.release.tag_name }}
${{ secrets.MIXPANEL_PROJECT_ID }}
${{ secrets.MIXPANEL_SERVICE_ACCOUNT_USERNAME }}
${{ secrets.MIXPANEL_SERVICE_ACCOUNT_SECRET }}

13
.gitignore vendored
View File

@@ -7,5 +7,14 @@
/crates/collab/static/styles.css
/vendor/bin
/assets/themes/*.json
/assets/themes/internal/*.json
/assets/themes/experiments/*.json
/assets/themes/Internal/*.json
/assets/themes/Experiments/*.json
**/venv
.build
Packages
*.xcodeproj
xcuserdata/
DerivedData/
.swiftpm/config/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "crates/live_kit_server/protocol"]
path = crates/live_kit_server/protocol
url = https://github.com/livekit/protocol

1726
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,69 @@
[workspace]
members = ["crates/*"]
members = [
"crates/activity_indicator",
"crates/assets",
"crates/auto_update",
"crates/breadcrumbs",
"crates/call",
"crates/cli",
"crates/client",
"crates/clock",
"crates/collab",
"crates/collab_ui",
"crates/collections",
"crates/command_palette",
"crates/context_menu",
"crates/db",
"crates/diagnostics",
"crates/drag_and_drop",
"crates/editor",
"crates/file_finder",
"crates/fs",
"crates/fsevent",
"crates/fuzzy",
"crates/git",
"crates/go_to_line",
"crates/gpui",
"crates/gpui_macros",
"crates/journal",
"crates/language",
"crates/live_kit_client",
"crates/live_kit_server",
"crates/lsp",
"crates/media",
"crates/menu",
"crates/outline",
"crates/picker",
"crates/plugin",
"crates/plugin_macros",
"crates/plugin_runtime",
"crates/project",
"crates/project_panel",
"crates/project_symbols",
"crates/rope",
"crates/rpc",
"crates/search",
"crates/settings",
"crates/snippet",
"crates/sum_tree",
"crates/terminal",
"crates/text",
"crates/theme",
"crates/theme_selector",
"crates/theme_testbench",
"crates/util",
"crates/vim",
"crates/workspace",
"crates/zed",
]
default-members = ["crates/zed"]
resolver = "2"
[workspace.dependencies]
serde = { version = "1.0", features = ["derive", "rc"] }
serde_json = { version = "1.0", features = ["preserve_order", "raw_value"] }
rand = { version = "0.8" }
[patch.crates-io]
tree-sitter = { git = "https://github.com/tree-sitter/tree-sitter", rev = "366210ae925d7ea0891bc7a0c738f60c77c04d7b" }
async-task = { git = "https://github.com/zed-industries/async-task", rev = "341b57d6de98cdfd7b418567b8de2022ca993a6e" }
@@ -13,11 +74,10 @@ cocoa-foundation = { git = "https://github.com/servo/core-foundation-rs", rev =
core-foundation = { git = "https://github.com/servo/core-foundation-rs", rev = "079665882507dd5e2ff77db3de5070c1f6c0fb85" }
core-foundation-sys = { git = "https://github.com/servo/core-foundation-rs", rev = "079665882507dd5e2ff77db3de5070c1f6c0fb85" }
core-graphics = { git = "https://github.com/servo/core-foundation-rs", rev = "079665882507dd5e2ff77db3de5070c1f6c0fb85" }
# TODO - Remove when a new version of RustRocksDB is released
rocksdb = { git = "https://github.com/rust-rocksdb/rust-rocksdb", rev = "39dc822dde743b2a26eb160b660e8fbdab079d49" }
[profile.dev]
split-debuginfo = "unpacked"
[profile.release]
debug = true

View File

@@ -1,6 +1,6 @@
# syntax = docker/dockerfile:1.2
FROM rust:1.62-bullseye as builder
FROM rust:1.64-bullseye as builder
WORKDIR app
COPY . .
@@ -19,5 +19,7 @@ FROM debian:bullseye-slim as runtime
RUN apt-get update; \
apt-get install -y --no-install-recommends libcurl4-openssl-dev ca-certificates
WORKDIR app
COPY --from=builder /app/collab /app
COPY --from=builder /app/collab /app/collab
COPY --from=builder /app/crates/collab/migrations /app/migrations
ENV MIGRATIONS_PATH=/app/migrations
ENTRYPOINT ["/app/collab"]

View File

@@ -1,15 +0,0 @@
# syntax = docker/dockerfile:1.2
FROM rust:1.62-bullseye as builder
WORKDIR app
RUN --mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=./target \
cargo install sqlx-cli --root=/app --target-dir=/app/target --version 0.5.7
FROM debian:bullseye-slim as runtime
RUN apt-get update; \
apt-get install -y --no-install-recommends libssl1.1
WORKDIR app
COPY --from=builder /app/bin/sqlx /app
COPY ./crates/collab/migrations /app/migrations
ENTRYPOINT ["/app/sqlx", "migrate", "run"]

View File

@@ -1,2 +1,3 @@
web: cd ../zed.dev && PORT=3000 npx next dev
collab: cd crates/collab && cargo run
web: cd ../zed.dev && PORT=3000 npx vercel dev
collab: cd crates/collab && cargo run serve
livekit: livekit-server --dev

View File

@@ -6,36 +6,43 @@ Welcome to Zed, a lightning-fast, collaborative code editor that makes your drea
## Development tips
### Dependencies
* Install [Postgres.app](https://postgresapp.com) and start it.
* Install the `LiveKit` server and the `foreman` process supervisor:
```
brew install livekit
brew install foreman
```
* Ensure the Zed.dev website is checked out in a sibling directory:
```
cd ..
git clone https://github.com/zed-industries/zed.dev
```
* Set up a local `zed` database and seed it with some initial users:
```
script/bootstrap
```
### Testing against locally-running servers
Make sure you have `zed.dev` cloned as a sibling to this repo.
Start the web and collab servers:
```
cd ..
git clone https://github.com/zed-industries/zed.dev
```
Make sure your local database is created, migrated, and seeded with initial data. Install [Postgres](https://postgresapp.com), then from the `zed` repository root, run:
```
script/sqlx database create
script/sqlx migrate run
script/seed-db
```
Run the web frontend and the collaboration server.
```
brew install foreman
foreman start
```
If you want to run Zed pointed at the local servers, you can run:
```
script/zed_with_local_servers
script/zed-with-local-servers
# or...
script/zed_with_local_servers --release
script/zed-with-local-servers --release
```
### Dump element JSON

View File

@@ -1,3 +1,10 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_430_1271)">
<path d="M10.9007 7.45347L6.60649 11.7477C6.44009 11.9168 6.22001 12 5.99993 12C5.77985 12 5.56031 11.9161 5.39283 11.7484L1.09859 7.45414C0.763098 7.11865 0.763098 6.57516 1.09859 6.23967C1.43407 5.90419 1.97756 5.90419 2.31305 6.23967L5.14108 9.06904V0.834694C5.14108 0.359912 5.52568 0 5.97577 0C6.42587 0 6.85878 0.359912 6.85878 0.834694V9.06891L9.68761 6.24008C10.0231 5.90459 10.5666 5.90459 10.9021 6.24008C11.2376 6.57556 11.2362 7.11771 10.9007 7.4532V7.45347Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1271">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 590 B

After

Width:  |  Height:  |  Size: 734 B

View File

@@ -1,3 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.0538 9.45347L8.75952 13.7477C8.59312 13.9168 8.37304 14 8.15296 14C7.93288 14 7.71334 13.9161 7.54586 13.7484L3.25162 9.45414C2.91613 9.11865 2.91613 8.57516 3.25162 8.23967C3.5871 7.90419 4.13059 7.90419 4.46608 8.23967L7.29411 11.069V2.83469C7.29411 2.35991 7.67871 2 8.1288 2C8.5789 2 9.01181 2.35991 9.01181 2.83469V11.0689L11.8406 8.24008C12.1761 7.90459 12.7196 7.90459 13.0551 8.24008C13.3906 8.57556 13.3893 9.11771 13.0538 9.4532V9.45347Z" fill="white"/>
<path d="M13.0538 9.45347L8.75952 13.7477C8.59312 13.9168 8.37304 14 8.15296 14C7.93288 14 7.71334 13.9161 7.54586 13.7484L3.25162 9.45414C2.91613 9.11865 2.91613 8.57516 3.25162 8.23967C3.5871 7.90418 4.13059 7.90418 4.46608 8.23967L7.29411 11.069V2.83469C7.29411 2.35991 7.67871 2 8.12881 2C8.5789 2 9.01181 2.35991 9.01181 2.83469V11.0689L11.8406 8.24008C12.1761 7.90459 12.7196 7.90459 13.0551 8.24008C13.3906 8.57556 13.3893 9.11771 13.0538 9.4532V9.45347Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 580 B

After

Width:  |  Height:  |  Size: 581 B

View File

@@ -1,3 +1,10 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_430_1354)">
<path d="M7.26716 4.96898L4.40433 7.83181C4.2934 7.94453 4.14668 8 3.99996 8C3.85324 8 3.70688 7.94409 3.59523 7.83226L0.732395 4.96943C0.508737 4.74577 0.508737 4.38344 0.732395 4.15978C0.956054 3.93612 1.31838 3.93612 1.54204 4.15978L3.42739 6.04603V0.556463C3.42739 0.239941 3.68379 0 3.98385 0C4.28392 0 4.57252 0.239941 4.57252 0.556463V6.04594L6.45841 4.16005C6.68207 3.93639 7.0444 3.93639 7.26806 4.16005C7.49172 4.38371 7.49082 4.74514 7.26716 4.9688V4.96898Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1354">
<rect width="8" height="8" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 584 B

After

Width:  |  Height:  |  Size: 726 B

View File

@@ -1,3 +1,10 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_430_1272)">
<path d="M12 6.00001C12 6.47507 11.6403 6.85889 11.1653 6.85889H2.93347L5.7624 9.68781C6.0979 10.0233 6.0979 10.5668 5.7624 10.9023C5.59331 11.0701 5.37322 11.1533 5.15313 11.1533C4.93305 11.1533 4.71349 11.0694 4.54601 10.9017L0.251624 6.60726C-0.0838748 6.27176 -0.0838748 5.72825 0.251624 5.39275L4.54601 1.09837C4.88151 0.762866 5.42502 0.762866 5.76052 1.09837C6.09602 1.43386 6.09602 1.97737 5.76052 2.31287L2.93347 5.14113H11.1653C11.6403 5.14113 12 5.52494 12 6.00001Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1272">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 596 B

After

Width:  |  Height:  |  Size: 740 B

View File

@@ -1,3 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14 8.15327C14 8.62833 13.6403 9.01214 13.1653 9.01214H4.93347L7.7624 11.8411C8.0979 12.1766 8.0979 12.7201 7.7624 13.0556C7.59331 13.2233 7.37322 13.3065 7.15313 13.3065C6.93305 13.3065 6.71349 13.2227 6.54601 13.0549L2.25162 8.76052C1.91613 8.42502 1.91613 7.88151 2.25162 7.54601L6.54601 3.25162C6.88151 2.91613 7.42502 2.91613 7.76052 3.25162C8.09602 3.58712 8.09602 4.13063 7.76052 4.46613L4.93347 7.29439H13.1653C13.6403 7.29439 14 7.6782 14 8.15327Z" fill="white"/>
<path d="M14 8.15327C14 8.62833 13.6403 9.01215 13.1653 9.01215H4.93347L7.7624 11.8411C8.0979 12.1766 8.0979 12.7201 7.7624 13.0556C7.59331 13.2233 7.37322 13.3065 7.15313 13.3065C6.93305 13.3065 6.71349 13.2227 6.54601 13.0549L2.25162 8.76052C1.91613 8.42502 1.91613 7.88151 2.25162 7.54601L6.54601 3.25162C6.88151 2.91613 7.42502 2.91613 7.76052 3.25162C8.09602 3.58712 8.09602 4.13063 7.76052 4.46613L4.93347 7.29439H13.1653C13.6403 7.29439 14 7.6782 14 8.15327Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 585 B

After

Width:  |  Height:  |  Size: 585 B

View File

@@ -1,3 +1,10 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_430_1355)">
<path d="M8 4.00003C8 4.31674 7.76023 4.57261 7.44352 4.57261H1.95565L3.8416 6.45856C4.06527 6.68223 4.06527 7.04457 3.8416 7.26823C3.72887 7.38007 3.58215 7.43554 3.43542 7.43554C3.2887 7.43554 3.14233 7.37962 3.03068 7.26779L0.16775 4.40486C-0.0559165 4.1812 -0.0559165 3.81886 0.16775 3.59519L3.03068 0.732264C3.25434 0.508598 3.61668 0.508598 3.84035 0.732264C4.06401 0.95593 4.06401 1.31827 3.84035 1.54194L1.95565 3.42744H7.44352C7.76023 3.42744 8 3.68331 8 4.00003Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1355">
<rect width="8" height="8" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 588 B

After

Width:  |  Height:  |  Size: 730 B

View File

@@ -1,3 +1,10 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_430_1273)">
<path d="M11.749 6.60576L7.46298 10.8917C7.2969 11.0605 7.07724 11.1436 6.85758 11.1436C6.63793 11.1436 6.41881 11.0598 6.25165 10.8924C5.91681 10.5576 5.91681 10.0151 6.25165 9.68029L9.07558 6.85756H0.857198C0.383864 6.85756 0 6.4745 0 6.00036C0 5.52623 0.383596 5.14317 0.85693 5.14317H9.07531L6.25192 2.31977C5.91708 1.98493 5.91708 1.44248 6.25192 1.10764C6.58676 0.772796 7.12921 0.772796 7.46405 1.10764L11.75 5.39363C12.0835 5.72981 12.0835 6.27092 11.7487 6.60576H11.749Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1273">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 599 B

After

Width:  |  Height:  |  Size: 743 B

View File

@@ -1,3 +1,10 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_430_1356)">
<path d="M7.83265 4.40382L4.97532 7.26115C4.8646 7.37365 4.71816 7.42901 4.57172 7.42901C4.42528 7.42901 4.2792 7.37321 4.16777 7.26159C3.94454 7.03836 3.94454 6.67673 4.16777 6.4535L6.05039 4.57169H0.571465C0.255909 4.57169 0 4.31631 0 4.00022C0 3.68413 0.255731 3.42876 0.571287 3.42876H6.05021L4.16795 1.54649C3.94472 1.32326 3.94472 0.961634 4.16795 0.738405C4.39117 0.515177 4.75281 0.515177 4.97603 0.738405L7.83336 3.59573C8.0557 3.81985 8.0557 4.18059 7.83247 4.40382H7.83265Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1356">
<rect width="8" height="8" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 600 B

After

Width:  |  Height:  |  Size: 742 B

View File

@@ -1,3 +1,10 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_430_1274)">
<path d="M10.9009 5.7604C10.7345 5.92948 10.5144 6.01268 10.2943 6.01268C10.0742 6.01268 9.85471 5.92881 9.68724 5.76107L6.85903 2.93408V11.1653C6.85903 11.6401 6.47444 12 6.02437 12C5.57429 12 5.14139 11.6404 5.14139 11.1653V2.93408L2.31346 5.76013C1.97798 6.09561 1.43451 6.09561 1.09903 5.76013C0.763558 5.42466 0.763558 4.88119 1.09903 4.54571L5.39314 0.251607C5.72861 -0.0838692 6.27209 -0.0838692 6.60756 0.251607L10.9017 4.54571C11.2363 4.88253 11.2363 5.42466 10.9009 5.76013V5.7604Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1274">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 611 B

After

Width:  |  Height:  |  Size: 755 B

View File

@@ -1,3 +1,10 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_430_1357)">
<path d="M7.26724 3.84027C7.15631 3.95299 7.0096 4.00845 6.86288 4.00845C6.71617 4.00845 6.56981 3.95254 6.45816 3.84072L4.57269 1.95605V7.44356C4.57269 7.76007 4.3163 8 4.01625 8C3.7162 8 3.4276 7.76025 3.4276 7.44356V1.95605L1.54231 3.84009C1.31866 4.06374 0.956346 4.06374 0.732695 3.84009C0.509044 3.61644 0.509044 3.25412 0.732695 3.03047L3.59543 0.167738C3.81908 -0.0559128 4.1814 -0.0559128 4.40505 0.167738L7.26778 3.03047C7.49089 3.25502 7.49089 3.61644 7.26724 3.84009V3.84027Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1357">
<rect width="8" height="8" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 603 B

After

Width:  |  Height:  |  Size: 745 B

View File

@@ -1,3 +1,3 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.17314 8L5.89399 3.29329L6.20495 7.94346L8 6.14841L7.67491 0.339222L1.85159 0L0.0565371 1.79505L4.70671 2.12014L0 6.82685L1.17314 8Z" fill="white"/>
<path d="M6 2H6.5C6.5 1.86739 6.44732 1.74021 6.35355 1.64645C6.25979 1.55268 6.13261 1.5 6 1.5V2ZM2 1.5C1.72386 1.5 1.5 1.72386 1.5 2C1.5 2.27614 1.72386 2.5 2 2.5L2 1.5ZM5.5 6C5.5 6.27614 5.72386 6.5 6 6.5C6.27614 6.5 6.5 6.27614 6.5 6H5.5ZM1.64645 5.64645C1.45118 5.84171 1.45118 6.15829 1.64645 6.35355C1.84171 6.54882 2.15829 6.54882 2.35355 6.35355L1.64645 5.64645ZM6 1.5H2L2 2.5H6V1.5ZM5.5 2V6H6.5V2H5.5ZM5.64645 1.64645L1.64645 5.64645L2.35355 6.35355L6.35355 2.35355L5.64645 1.64645Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 259 B

After

Width:  |  Height:  |  Size: 608 B

View File

@@ -1,3 +1,3 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.14029 5.25005H9.75348C10.0652 5.25005 10.3464 5.44457 10.4355 5.73518C10.5644 6.02814 10.4824 6.3586 10.248 6.56484L4.24822 11.8146C3.98338 12.0443 3.59598 12.0631 3.31286 11.8568C3.02951 11.6506 2.92639 11.2756 3.06443 10.9545L4.86694 6.74999H2.23267C1.94135 6.74999 1.66152 6.55546 1.5516 6.26485C1.44171 5.97189 1.52465 5.64144 1.75986 5.43519L7.75893 0.185629C8.02376 -0.0449871 8.41046 -0.0625645 8.69405 0.143209C8.97763 0.349123 9.08075 0.723265 8.94248 1.04542L7.1402 5.24972L7.14029 5.25005Z" fill="white"/>
<path d="M7.01442 5.33285H9.33914C9.61643 5.33285 9.86663 5.5059 9.94586 5.76443C10.0605 6.02505 9.98756 6.31903 9.77906 6.50251L4.4416 11.1728C4.206 11.3771 3.86136 11.3938 3.6095 11.2103C3.35743 11.0268 3.26569 10.6932 3.38849 10.4076L4.99202 6.66722H2.64855C2.38939 6.66722 2.14044 6.49417 2.04266 6.23563C1.9449 5.97501 2.01868 5.68104 2.22793 5.49756L7.56476 0.827491C7.80036 0.622333 8.14438 0.606695 8.39666 0.789754C8.64894 0.972937 8.74067 1.30578 8.61766 1.59237L7.01434 5.33256L7.01442 5.33285Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 632 B

After

Width:  |  Height:  |  Size: 625 B

View File

@@ -1,3 +1,3 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4.76019 3.50003H6.50231C6.71012 3.50003 6.89761 3.62971 6.95698 3.82346C7.04292 4.01876 6.98823 4.23906 6.83199 4.37656L2.83214 7.87643C2.65558 8.02954 2.39731 8.04204 2.20857 7.90455C2.01967 7.76705 1.95092 7.51706 2.04295 7.30301L3.24462 4.49999H1.48844C1.29423 4.49999 1.10767 4.37031 1.0344 4.17657C0.961132 3.98126 1.01643 3.76096 1.17323 3.62346L5.17261 0.123753C5.34917 -0.0299914 5.60697 -0.0417097 5.79603 0.0954726C5.98508 0.232749 6.05383 0.482177 5.96164 0.69695L4.76013 3.49981L4.76019 3.50003Z" fill="white"/>
<path d="M4.76019 3.50003H6.50231C6.71012 3.50003 6.89761 3.62971 6.95698 3.82346C7.04292 4.01876 6.98823 4.23906 6.83199 4.37656L2.83214 7.87643C2.65558 8.02954 2.39731 8.04204 2.20857 7.90455C2.01967 7.76705 1.95092 7.51706 2.04295 7.30301L3.24462 4.49999H1.48844C1.29423 4.49999 1.10767 4.37031 1.0344 4.17657C0.961132 3.98126 1.01643 3.76096 1.17323 3.62346L5.17261 0.123753C5.34917 -0.0299914 5.60697 -0.0417097 5.79603 0.0954726C5.98508 0.232749 6.05383 0.482177 5.96165 0.69695L4.76013 3.49981L4.76019 3.50003Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 633 B

After

Width:  |  Height:  |  Size: 633 B

View File

@@ -1,3 +1,10 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4.00788 3.83701L7.62903 0.754503C7.87479 0.546451 8.23364 0.530593 8.4968 0.716233C8.75996 0.901999 8.85565 1.23953 8.72734 1.53017L7.05487 5.3231H9.47984C9.7691 5.3231 10.0301 5.49859 10.1127 5.76077C10.2323 6.02506 10.1562 6.32318 9.93874 6.50925L8.79258 7.48396L11.7998 9.86631C12.026 10.0397 12.0673 10.3589 11.889 10.5788C11.7106 10.7987 11.3822 10.8389 11.156 10.6655L0.200158 2.51988C-0.0268974 2.34693 -0.0666975 2.02808 0.111206 1.80735C0.28911 1.58661 0.616862 1.54792 0.843918 1.72108L4.00788 3.83701ZM2.06138 5.49043L2.40718 5.17751L4.34064 6.67658H2.52027C2.23102 6.67658 1.97003 6.50109 1.86782 6.23891C1.76777 5.97461 1.84389 5.67649 2.06138 5.49043ZM3.27278 10.4697L4.79301 7.02333L7.18318 8.83533L4.37108 11.2457C4.12532 11.4529 3.76647 11.4698 3.50331 11.2837C3.24015 11.0977 3.14446 10.7594 3.27278 10.4697Z" fill="white"/>
<g clip-path="url(#clip0_430_1336)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.01443 5.33285H9.33914C9.61644 5.33285 9.86663 5.5059 9.94586 5.76443C10.0605 6.02505 9.98756 6.31903 9.77906 6.50251L9.11489 7.08366L11.4605 8.90799C11.7874 9.16229 11.8463 9.6335 11.592 9.96045C11.3377 10.2874 10.8665 10.3463 10.5395 10.092L1.53955 3.09201C1.21259 2.83771 1.15369 2.3665 1.40799 2.03954C1.66229 1.71258 2.1335 1.65368 2.46046 1.90799L4.50911 3.50138L7.56477 0.827491C7.80037 0.622333 8.14438 0.606695 8.39666 0.789754C8.64894 0.972937 8.74068 1.30578 8.61767 1.59237L7.01434 5.33256L7.01443 5.33285ZM2.88883 4.91923L7.49455 8.50146L4.4416 11.1728C4.206 11.3771 3.86136 11.3938 3.6095 11.2103C3.35743 11.0268 3.26569 10.6932 3.3885 10.4076L4.99203 6.66722H2.64855C2.38939 6.66722 2.14045 6.49416 2.04266 6.23563C1.9449 5.97501 2.01869 5.68104 2.22793 5.49756L2.88883 4.91923Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1336">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 956 B

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,9 +1,9 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_430_1350)">
<path d="M2.8102 2.0687L5.08603 0.503002C5.24987 0.364301 5.4891 0.353729 5.66454 0.477489C5.83998 0.601333 5.90377 0.826356 5.81823 1.02011L4.70325 3.54873H6.3199C6.51274 3.54873 6.68673 3.66573 6.74182 3.84051C6.82157 4.01671 6.77082 4.21546 6.62583 4.3395L6.22432 4.68222L8.0048 6.08823C8.15559 6.20381 8.18314 6.41666 8.06425 6.56325C7.94536 6.70985 7.72642 6.73663 7.57563 6.62104L0.271717 1.19061C0.120346 1.07531 0.093813 0.862748 0.212416 0.715589C0.331018 0.56843 0.54952 0.542635 0.70089 0.658079L2.8102 2.0687ZM1.37426 3.66029L1.60479 3.45167L2.89376 4.45105H1.68019C1.48735 4.45105 1.31336 4.33406 1.24521 4.15927C1.17852 3.98308 1.22927 3.78433 1.37426 3.66029ZM2.18186 6.97981L3.19534 4.68222L4.78879 5.89022L2.91406 7.49712C2.75022 7.63526 2.51099 7.64653 2.33555 7.52249C2.16011 7.39845 2.09631 7.17292 2.18186 6.97981Z" fill="white"/>
<g clip-path="url(#clip0_702_132)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.67628 3.55525H6.22609C6.41096 3.55525 6.57775 3.67062 6.63057 3.84298C6.70702 4.01672 6.65837 4.21271 6.51937 4.33502L6.07659 4.72246L7.6403 5.93868C7.85828 6.10821 7.89754 6.42235 7.72801 6.64032C7.55847 6.8583 7.24434 6.89756 7.02636 6.72803L1.02636 2.06136C0.808388 1.89183 0.769121 1.57769 0.938656 1.35972C1.10819 1.14174 1.42233 1.10248 1.6403 1.27201L3.00607 2.33428L5.04318 0.551681C5.20024 0.414909 5.42959 0.404484 5.59777 0.526523C5.76596 0.648645 5.82712 0.870539 5.74511 1.0616L4.67622 3.55506L4.67628 3.55525ZM3.25023 4.62627L4.80474 5.83533L2.96106 7.44854C2.804 7.58476 2.57424 7.59588 2.40633 7.47356C2.23828 7.35125 2.17713 7.12885 2.25899 6.93843L3.25023 4.62627ZM1.73426 3.44719L3.01695 4.44483H1.7657C1.59292 4.44483 1.42696 4.32946 1.36177 4.15711C1.2966 3.98336 1.34579 3.78738 1.48528 3.66506L1.73426 3.44719Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1350">
<clipPath id="clip0_702_132">
<rect width="8" height="8" fill="white"/>
</clipPath>
</defs>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,3 +1,10 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.78057 2.96296L4.59642 6.16966C4.41855 6.32749 4.21312 6.40515 4.00769 6.40515C3.80226 6.40515 3.59733 6.32686 3.44075 6.17028L0.256599 2.96358C0.00482339 2.73498 -0.06382 2.38913 0.0601891 2.09088C0.184298 1.79276 0.47686 1.59485 0.800787 1.59485H7.19164C7.51582 1.59485 7.80843 1.78976 7.93269 2.08963C8.05695 2.38926 8.01085 2.73473 7.78037 2.96271L7.78057 2.96296Z" fill="white"/>
<g clip-path="url(#clip0_430_1359)">
<path d="M6.36286 3.35324L4.37276 5.35315C4.26159 5.45158 4.1332 5.50002 4.0048 5.50002C3.87641 5.50002 3.74833 5.45119 3.65047 5.35354L1.66037 3.35363C1.50301 3.21106 1.46011 2.99537 1.53762 2.80936C1.61519 2.62343 1.79804 2.5 2.00049 2.5H5.99478C6.19739 2.5 6.38027 2.62156 6.45793 2.80858C6.53559 2.99545 6.50678 3.2109 6.36273 3.35309L6.36286 3.35324Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1359">
<rect width="8" height="8" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 495 B

After

Width:  |  Height:  |  Size: 613 B

View File

@@ -1,3 +1,10 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.03717 7.78065L1.83086 4.59689C1.67355 4.41904 1.5954 4.21363 1.5954 3.98568C1.5954 3.75774 1.67368 3.57538 1.83011 3.41882L5.03641 0.235058C5.26562 0.00560697 5.61029 -0.0630281 5.91013 0.0609657C6.20997 0.18496 6.40461 0.478537 6.40461 0.801672V7.19174C6.40461 7.51588 6.20947 7.80845 5.90988 7.9327C5.61004 8.05694 5.26486 8.01085 5.03692 7.7804L5.03717 7.78065Z" fill="white"/>
<g clip-path="url(#clip0_430_1360)">
<path d="M4.64677 6.36286L2.64687 4.37276C2.54843 4.26159 2.5 4.1332 2.5 4.0048C2.5 3.87641 2.54882 3.74833 2.64648 3.65047L4.64638 1.66037C4.78895 1.50301 5.00465 1.46011 5.19065 1.53762C5.37658 1.61519 5.50002 1.79804 5.50002 2.00049L5.50002 5.99478C5.50002 6.19739 5.37846 6.38027 5.19144 6.45793C5.00457 6.53559 4.78911 6.50678 4.64693 6.36273L4.64677 6.36286Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1360">
<rect width="8" height="8" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 492 B

After

Width:  |  Height:  |  Size: 622 B

View File

@@ -1,3 +1,10 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.95931 0.236879L6.17709 3.43204C6.33546 3.61052 6.4134 3.81666 6.4134 4.00018C6.4134 4.18369 6.33484 4.41195 6.17772 4.56907L2.95993 7.76423C2.72966 7.99425 2.384 8.06338 2.08309 7.93869C1.78217 7.81401 1.58659 7.56463 1.58659 7.21771V0.804768C1.58659 0.47947 1.78217 0.185847 2.08309 0.0611582C2.38375 -0.0635309 2.73042 0.0061038 2.95918 0.236628L2.95931 0.236879Z" fill="white"/>
<g clip-path="url(#clip0_430_1361)">
<path d="M3.35323 1.63714L5.35313 3.62724C5.45157 3.73841 5.5 3.8668 5.5 3.9952C5.5 4.12359 5.45118 4.25167 5.35352 4.34953L3.35362 6.33963C3.21105 6.49699 2.99535 6.53989 2.80935 6.46238C2.62342 6.38481 2.49998 6.20196 2.49998 5.99951L2.49998 2.00522C2.49998 1.80261 2.62154 1.61973 2.80856 1.54207C2.99543 1.46441 3.21089 1.49322 3.35307 1.63727L3.35323 1.63714Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1361">
<rect width="8" height="8" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 493 B

After

Width:  |  Height:  |  Size: 622 B

View File

@@ -1,3 +1,10 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0.235788 5.03793L3.42201 1.82915C3.60024 1.67122 3.80581 1.59351 4.01137 1.59351C4.21693 1.59351 4.42199 1.67185 4.57867 1.82852L7.76489 5.0373C7.99427 5.26668 8.06321 5.61163 7.93887 5.9117C7.81453 6.21177 7.54328 6.40655 7.19734 6.40655H0.802589C0.478202 6.40655 0.1854 6.21127 0.0610601 5.91145C-0.0632802 5.61137 0.00590919 5.26593 0.235538 5.03781L0.235788 5.03793Z" fill="white"/>
<g clip-path="url(#clip0_430_1362)">
<path d="M1.63714 4.64676L3.62724 2.64685C3.73841 2.54842 3.8668 2.49998 3.9952 2.49998C4.12359 2.49998 4.25167 2.54881 4.34953 2.64646L6.33963 4.64637C6.49699 4.78894 6.53989 5.00463 6.46238 5.19064C6.38481 5.37657 6.20196 5.5 5.99951 5.5L2.00522 5.5C1.80261 5.5 1.61973 5.37844 1.54207 5.19142C1.46441 5.00455 1.49322 4.7891 1.63727 4.64691L1.63714 4.64676Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1362">
<rect width="8" height="8" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 496 B

After

Width:  |  Height:  |  Size: 617 B

View File

@@ -1,3 +1,3 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.28561 8C2.13936 8 1.99311 7.9442 1.88168 7.83259C1.65846 7.60937 1.65846 7.24776 1.88168 7.02454L4.90707 3.99996L1.88168 0.975457C1.65846 0.75224 1.65846 0.390629 1.88168 0.167413C2.10489 -0.0558042 2.4665 -0.0558042 2.68972 0.167413L6.11833 3.59602C6.34155 3.81924 6.34155 4.18085 6.11833 4.40407L2.68972 7.83268C2.57847 7.94464 2.43204 8 2.28561 8Z" fill="white"/>
<path d="M2.28561 8C2.13936 8 1.99311 7.9442 1.88168 7.83259C1.65846 7.60937 1.65846 7.24776 1.88168 7.02454L4.90707 3.99996L1.88168 0.975457C1.65846 0.752241 1.65846 0.390629 1.88168 0.167413C2.10489 -0.0558042 2.4665 -0.0558042 2.68972 0.167413L6.11833 3.59602C6.34155 3.81924 6.34155 4.18085 6.11833 4.40407L2.68972 7.83268C2.57847 7.94464 2.43204 8 2.28561 8Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 478 B

After

Width:  |  Height:  |  Size: 479 B

View File

@@ -1,3 +1,10 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_430_1285)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6 12C9.31371 12 12 9.31371 12 6C12 2.68629 9.31371 0 6 0C2.68629 0 0 2.68629 0 6C0 9.31371 2.68629 12 6 12ZM9.53033 4.28033L8.46967 3.21967L4.875 6.81434L3.53033 5.46967L2.46967 6.53033L4.875 8.93566L9.53033 4.28033Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1285">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 386 B

After

Width:  |  Height:  |  Size: 530 B

View File

@@ -1,3 +1,10 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_430_1370)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 8C6.20914 8 8 6.20914 8 4C8 1.79086 6.20914 0 4 0C1.79086 0 0 1.79086 0 4C0 6.20914 1.79086 8 4 8ZM6.35355 2.85355L5.64645 2.14645L3.25 4.54289L2.35355 3.64645L1.64645 4.35355L3.25 5.95711L6.35355 2.85355Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1370">
<rect width="8" height="8" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 373 B

After

Width:  |  Height:  |  Size: 515 B

View File

@@ -1,3 +1,10 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_430_1294)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 6C12 9.31371 9.31371 12 6 12C2.68629 12 0 9.31371 0 6C0 2.68629 2.68629 0 6 0C9.31371 0 12 2.68629 12 6ZM5.25 6H4.5V4.5H6.75V8.25H7.5V9.75H5.25V6ZM6.75 3.75V2.25H5.25V3.75H6.75Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1294">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 350 B

After

Width:  |  Height:  |  Size: 494 B

View File

@@ -1,3 +1,10 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_430_1372)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 4C8 6.20914 6.20914 8 4 8C1.79086 8 0 6.20914 0 4C0 1.79086 1.79086 0 4 0C6.20914 0 8 1.79086 8 4ZM3.5 4H3V3H4.5V5.5H5V6.5H3.5V4ZM4.5 2.5V1.5H3.5V2.5H4.5Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1372">
<rect width="8" height="8" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 322 B

After

Width:  |  Height:  |  Size: 464 B

View File

@@ -1,3 +1,10 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_430_1287)">
<path d="M6 0C2.68594 0 0 2.68594 0 6C0 9.31406 2.68594 12 6 12C9.31406 12 12 9.31406 12 6C12 2.68594 9.31406 0 6 0ZM8.97187 5.76797C8.91328 5.90859 8.77734 6 8.625 6H7.125V8.25C7.125 8.66414 6.78914 9 6.375 9H5.625C5.21086 9 4.875 8.66414 4.875 8.25V6H3.375C3.22266 6 3.08672 5.90859 3.02812 5.76797C2.96953 5.62734 3.00234 5.46797 3.11016 5.36016L5.73516 2.73516C5.88141 2.58867 6.11906 2.58867 6.26531 2.73516L8.89031 5.36016C8.99766 5.46797 9.03047 5.62734 8.97187 5.76797Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1287">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 597 B

After

Width:  |  Height:  |  Size: 741 B

View File

@@ -1,3 +1,10 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_430_1376)">
<path d="M4 0C1.79063 0 0 1.79063 0 4C0 6.20937 1.79063 8 4 8C6.20937 8 8 6.20937 8 4C8 1.79063 6.20937 0 4 0ZM5.98125 3.84531C5.94219 3.93906 5.85156 4 5.75 4H4.75V5.5C4.75 5.77609 4.52609 6 4.25 6H3.75C3.47391 6 3.25 5.77609 3.25 5.5V4H2.25C2.14844 4 2.05781 3.93906 2.01875 3.84531C1.97969 3.75156 2.00156 3.64531 2.07344 3.57344L3.82344 1.82344C3.92094 1.72578 4.07938 1.72578 4.17688 1.82344L5.92688 3.57344C5.99844 3.64531 6.02031 3.75156 5.98125 3.84531Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1376">
<rect width="8" height="8" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 577 B

After

Width:  |  Height:  |  Size: 719 B

View File

@@ -1,3 +1,10 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_430_1292)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6 12C9.31371 12 12 9.31371 12 6C12 2.68629 9.31371 0 6 0C2.68629 0 0 2.68629 0 6C0 9.31371 2.68629 12 6 12ZM3.21967 4.28033L4.93934 6L3.21967 7.71967L4.28033 8.78033L6 7.06066L7.71967 8.78033L8.78033 7.71967L7.06066 6L8.78033 4.28033L7.71967 3.21967L6 4.93934L4.28033 3.21967L3.21967 4.28033Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1292">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 462 B

After

Width:  |  Height:  |  Size: 606 B

View File

@@ -1,3 +1,10 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_430_1365)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 8C6.20914 8 8 6.20914 8 4C8 1.79086 6.20914 0 4 0C1.79086 0 0 1.79086 0 4C0 6.20914 1.79086 8 4 8ZM2.14645 2.85355L3.29289 4L2.14645 5.14645L2.85355 5.85355L4 4.70711L5.14645 5.85355L5.85355 5.14645L4.70711 4L5.85355 2.85355L5.14645 2.14645L4 3.29289L2.85355 2.14645L2.14645 2.85355Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1365">
<rect width="8" height="8" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 451 B

After

Width:  |  Height:  |  Size: 593 B

View File

@@ -1,3 +1,3 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.59892 2.76222C3.14641 2.17067 3.93013 1.80018 4.80011 1.80018C5.91195 1.80018 6.8813 2.40485 7.40066 3.30389C7.68565 3.09577 8.03064 3.00015 8.4 3.00015C9.39372 3.00015 10.1999 3.7895 10.1999 4.80009C10.1999 5.02884 10.1568 5.24633 10.08 5.44882C11.1749 5.67007 11.9999 6.63941 11.9999 7.8C11.9999 8.48623 11.7112 9.10497 11.233 9.52683L11.8274 9.99557C12.0224 10.1493 12.058 10.4324 11.9043 10.6274C11.7505 10.8224 11.4674 10.858 11.2724 10.7043L0.172556 2.00436C-0.0231882 1.85099 -0.0574997 1.56825 0.0958708 1.37251C0.249241 1.17676 0.531796 1.14245 0.727671 1.29582L2.59868 2.76184L2.59892 2.76222ZM1.82213 4.43635L9.13873 10.1999H2.70017C1.20903 10.1999 0.000248596 8.99059 0.000248596 7.50001C0.000248596 6.32255 0.753414 5.32133 1.80395 4.95196C1.80151 4.90134 1.8002 4.85072 1.8002 4.80009C1.8002 4.67635 1.8077 4.55448 1.82213 4.43635Z" fill="white"/>
<path d="M2.59892 2.76222C3.14641 2.17067 3.93013 1.80018 4.80011 1.80018C5.91195 1.80018 6.8813 2.40485 7.40066 3.30389C7.68565 3.09577 8.03064 3.00015 8.4 3.00015C9.39372 3.00015 10.1999 3.7895 10.1999 4.80009C10.1999 5.02884 10.1568 5.24633 10.08 5.44882C11.1749 5.67007 11.9999 6.63941 11.9999 7.80001C11.9999 8.48623 11.7112 9.10497 11.233 9.52683L11.8274 9.99557C12.0224 10.1493 12.058 10.4324 11.9043 10.6274C11.7505 10.8224 11.4674 10.858 11.2724 10.7043L0.172556 2.00436C-0.0231882 1.85099 -0.0574997 1.56825 0.0958708 1.37251C0.249241 1.17676 0.531795 1.14245 0.727671 1.29582L2.59868 2.76184L2.59892 2.76222ZM1.82213 4.43635L9.13873 10.1999H2.70017C1.20903 10.1999 0.000248596 8.99059 0.000248596 7.50001C0.000248596 6.32255 0.753414 5.32133 1.80395 4.95196C1.80151 4.90134 1.8002 4.85072 1.8002 4.80009C1.8002 4.67635 1.8077 4.55448 1.82213 4.43635Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 977 B

After

Width:  |  Height:  |  Size: 981 B

View File

@@ -1,3 +1,10 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.73261 1.8415C2.0976 1.44713 2.62009 1.20014 3.20007 1.20014C3.9413 1.20014 4.58753 1.60325 4.93377 2.20261C5.12376 2.06387 5.35376 2.00012 5.6 2.00012C6.26248 2.00012 6.79996 2.52635 6.79996 3.20008C6.79996 3.35258 6.77122 3.49757 6.71997 3.63257C7.44995 3.78007 7.99993 4.4263 7.99993 5.20002C7.99993 5.65751 7.80744 6.07 7.48869 6.35124L7.88493 6.66373C8.01493 6.76623 8.03868 6.95497 7.93618 7.08497C7.83368 7.21496 7.64494 7.23871 7.51494 7.13622L0.115037 1.33626C-0.0154588 1.23402 -0.0383331 1.04552 0.0639139 0.915025C0.166161 0.784529 0.35453 0.761655 0.485114 0.863902L1.73245 1.84125L1.73261 1.8415ZM1.21475 2.95759L6.09249 6.79998H1.80011C0.806017 6.79998 0.000165731 5.99375 0.000165731 5.00003C0.000165731 4.21505 0.502276 3.54757 1.20263 3.30133C1.20101 3.26758 1.20013 3.23383 1.20013 3.20008C1.20013 3.11759 1.20513 3.03634 1.21475 2.95759Z" fill="white"/>
<g clip-path="url(#clip0_430_1352)">
<path d="M1.73261 1.8415C2.0976 1.44713 2.62009 1.20014 3.20007 1.20014C3.9413 1.20014 4.58753 1.60325 4.93377 2.20261C5.12376 2.06387 5.35376 2.00012 5.6 2.00012C6.26248 2.00012 6.79997 2.52635 6.79997 3.20008C6.79997 3.35258 6.77122 3.49757 6.71997 3.63257C7.44995 3.78007 7.99993 4.4263 7.99993 5.20002C7.99993 5.65751 7.80744 6.07 7.48869 6.35124L7.88493 6.66373C8.01493 6.76623 8.03868 6.95497 7.93618 7.08497C7.83368 7.21496 7.64494 7.23871 7.51494 7.13622L0.115037 1.33626C-0.0154588 1.23402 -0.0383331 1.04552 0.0639139 0.915025C0.166161 0.784529 0.35453 0.761655 0.485114 0.863902L1.73245 1.84125L1.73261 1.8415ZM1.21475 2.95759L6.09249 6.79998H1.80011C0.806017 6.79998 0.000165731 5.99375 0.000165731 5.00003C0.000165731 4.21505 0.502276 3.54757 1.20263 3.30133C1.20101 3.26758 1.20013 3.23383 1.20013 3.20008C1.20013 3.11759 1.20513 3.03634 1.21475 2.95759Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1352">
<rect width="8" height="8" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 984 B

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,3 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11 0.666656H1C0.447917 0.666656 0 1.11457 0 1.66666V8.33332C0 8.88541 0.447917 9.33332 1 9.33332H5L4.66667 10.3333H3.16667C2.89167 10.3333 2.66667 10.5583 2.66667 10.8333C2.66667 11.1083 2.89167 11.3333 3.16667 11.3333H8.83333C9.10938 11.3333 9.33333 11.1094 9.33333 10.8333C9.33333 10.5573 9.10938 10.3333 8.83333 10.3333H7.33333L7 9.33332H11C11.5521 9.33332 12 8.88541 12 8.33332V1.66666C12 1.11457 11.5521 0.666656 11 0.666656ZM10.6667 7.99999H1.33333V1.99999H10.6667V7.99999Z" fill="#979DB4"/>
</svg>

After

Width:  |  Height:  |  Size: 611 B

View File

@@ -1,11 +1,10 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_616_81)">
<path opacity="0.6" d="M11 11L11 7L1 7L1 11L11 11Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.1818 1C1.51237 1 1.04544 1.48778 1.04544 2V10C1.04544 10.5122 1.51237 11 2.1818 11H9.81817C10.4876 11 10.9545 10.5122 10.9545 10V2C10.9545 1.48778 10.4876 1 9.81817 1H2.1818ZM0.0454407 2C0.0454407 0.855367 1.04377 0 2.1818 0H9.81817C10.9562 0 11.9545 0.855367 11.9545 2V10C11.9545 11.1446 10.9562 12 9.81817 12H2.1818C1.04377 12 0.0454407 11.1446 0.0454407 10V2Z" fill="white"/>
<path d="M11 8L11 7L1 7L1 8L11 8Z" fill="white"/>
<g clip-path="url(#clip0_702_214)">
<rect x="0.5" y="0.5" width="11" height="11" rx="1" stroke="white" stroke-opacity="0.4"/>
<path d="M12 7.5L12 10.5C12 11.3284 11.3284 12 10.5 12L1.5 12C0.671573 12 -1.67346e-07 11.3284 -1.31134e-07 10.5L0 7.5L12 7.5Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_616_81">
<clipPath id="clip0_702_214">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>

Before

Width:  |  Height:  |  Size: 791 B

After

Width:  |  Height:  |  Size: 478 B

View File

@@ -1,7 +1,7 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_610_112)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7 1H1V7H7V1ZM1 0C0.447715 0 4.37114e-08 0.447715 4.37114e-08 1V7C4.37114e-08 7.55228 0.447715 8 1 8H7C7.55228 8 8 7.55228 8 7V1C8 0.447715 7.55228 0 7 0H1Z" fill="white"/>
<path d="M7 4C7.55228 4 8 4.44772 8 5V7C8 7.55228 7.55228 8 7 8H1C0.447715 8 4.37114e-08 7.55228 4.37114e-08 7L0 5C2.41411e-08 4.44771 0.447715 4 1 4L7 4Z" fill="white"/>
<rect x="0.5" y="0.5" width="7" height="7" rx="0.5" stroke="white" stroke-opacity="0.4"/>
<path d="M8 5L8 7C8 7.55228 7.55228 8 7 8L1 8C0.447715 8 -1.11564e-07 7.55228 -8.74228e-08 7L0 5L8 5Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_610_112">

Before

Width:  |  Height:  |  Size: 632 B

After

Width:  |  Height:  |  Size: 447 B

View File

@@ -1,11 +0,0 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_616_82)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.1818 1C1.51237 1 1.04544 1.48778 1.04544 2V10C1.04544 10.5122 1.51237 11 2.1818 11H9.81817C10.4876 11 10.9545 10.5122 10.9545 10V2C10.9545 1.48778 10.4876 1 9.81817 1H2.1818ZM0.0454407 2C0.0454407 0.855367 1.04377 0 2.1818 0H9.81817C10.9562 0 11.9545 0.855367 11.9545 2V10C11.9545 11.1446 10.9562 12 9.81817 12H2.1818C1.04377 12 0.0454407 11.1446 0.0454407 10V2Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.5 4C5.5 3.72386 5.72386 3.5 6 3.5H8C8.27614 3.5 8.5 3.72386 8.5 4V6C8.5 6.27614 8.27614 6.5 8 6.5C7.72386 6.5 7.5 6.27614 7.5 6V5.20711L5.20711 7.5H6C6.27614 7.5 6.5 7.72386 6.5 8C6.5 8.27614 6.27614 8.5 6 8.5H4C3.72386 8.5 3.5 8.27614 3.5 8V6C3.5 5.72386 3.72386 5.5 4 5.5C4.27614 5.5 4.5 5.72386 4.5 6V6.79289L6.79289 4.5H6C5.72386 4.5 5.5 4.27614 5.5 4Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_616_82">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,13 +0,0 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_610_113)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7 1H1V7H7V1ZM1 0C0.447715 0 0 0.447715 0 1V7C0 7.55228 0.447715 8 1 8H7C7.55228 8 8 7.55228 8 7V1C8 0.447715 7.55228 0 7 0H1Z" fill="white"/>
<path d="M6 2H3L6 5V2Z" fill="white"/>
<path d="M2 6L5 6L2 3L2 6Z" fill="white"/>
<path d="M5.5 2.5L2.5 5.5" stroke="white"/>
</g>
<defs>
<clipPath id="clip0_610_113">
<rect width="8" height="8" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 557 B

View File

@@ -1,11 +1,10 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_620_198)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.1818 1C1.51237 1 1.04544 1.48778 1.04544 2V10C1.04544 10.5122 1.51237 11 2.1818 11H9.81817C10.4876 11 10.9545 10.5122 10.9545 10V2C10.9545 1.48778 10.4876 1 9.81817 1H2.1818ZM0.0454407 2C0.0454407 0.855367 1.04377 0 2.1818 0H9.81817C10.9562 0 11.9545 0.855367 11.9545 2V10C11.9545 11.1446 10.9562 12 9.81817 12H2.1818C1.04377 12 0.0454407 11.1446 0.0454407 10V2Z" fill="white"/>
<rect opacity="0.6" x="4" y="4" width="4" height="4" fill="white"/>
<rect x="3.5" y="3.5" width="5" height="5" rx="0.5" stroke="white"/>
<g clip-path="url(#clip0_702_213)">
<rect x="2" y="3" width="8" height="6" rx="1" fill="white"/>
<rect x="0.5" y="0.5" width="11" height="11" rx="1" stroke="white" stroke-opacity="0.4"/>
</g>
<defs>
<clipPath id="clip0_620_198">
<clipPath id="clip0_702_213">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>

Before

Width:  |  Height:  |  Size: 813 B

After

Width:  |  Height:  |  Size: 396 B

View File

@@ -1,6 +1,6 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_620_186)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7 1H1V7H7V1ZM1 0C0.447715 0 0 0.447715 0 1V7C0 7.55228 0.447715 8 1 8H7C7.55228 8 8 7.55228 8 7V1C8 0.447715 7.55228 0 7 0H1Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M7 1H1V7H7V1ZM1 0C0.447715 0 0 0.447715 0 1V7C0 7.55228 0.447715 8 1 8H7C7.55228 8 8 7.55228 8 7V1C8 0.447715 7.55228 0 7 0H1Z" fill="white" fill-opacity="0.4"/>
<rect x="2" y="2" width="4" height="4" fill="white"/>
</g>
<defs>

Before

Width:  |  Height:  |  Size: 485 B

After

Width:  |  Height:  |  Size: 504 B

View File

@@ -1,11 +1,10 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_616_83)">
<path opacity="0.6" d="M11 1H7V11H11V1Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.1818 1C1.51237 1 1.04544 1.48778 1.04544 2V10C1.04544 10.5122 1.51237 11 2.1818 11H9.81817C10.4876 11 10.9545 10.5122 10.9545 10V2C10.9545 1.48778 10.4876 1 9.81817 1H2.1818ZM0.0454407 2C0.0454407 0.855367 1.04377 0 2.1818 0H9.81817C10.9562 0 11.9545 0.855367 11.9545 2V10C11.9545 11.1446 10.9562 12 9.81817 12H2.1818C1.04377 12 0.0454407 11.1446 0.0454407 10V2Z" fill="white"/>
<path d="M8 1H7V11H8V1Z" fill="white"/>
<g clip-path="url(#clip0_702_215)">
<rect x="0.5" y="0.5" width="11" height="11" rx="1" stroke="white" stroke-opacity="0.4"/>
<path d="M7.5 0H10.5C11.3284 0 12 0.671573 12 1.5V10.5C12 11.3284 11.3284 12 10.5 12H7.5V0Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_616_83">
<clipPath id="clip0_702_215">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>

Before

Width:  |  Height:  |  Size: 770 B

After

Width:  |  Height:  |  Size: 443 B

View File

@@ -1,7 +1,7 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_610_114)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7 1H1V7H7V1ZM1 0C0.447715 0 0 0.447715 0 1V7C0 7.55228 0.447715 8 1 8H7C7.55228 8 8 7.55228 8 7V1C8 0.447715 7.55228 0 7 0H1Z" fill="white"/>
<path d="M4 1C4 0.447715 4.44772 0 5 0H7C7.55228 0 8 0.447715 8 1V7C8 7.55228 7.55228 8 7 8H5C4.44772 8 4 7.55228 4 7V1Z" fill="white"/>
<rect x="0.5" y="0.5" width="7" height="7" rx="0.5" stroke="white" stroke-opacity="0.4"/>
<path d="M5 0H7C7.55228 0 8 0.447715 8 1V7C8 7.55228 7.55228 8 7 8H5V0Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_610_114">

Before

Width:  |  Height:  |  Size: 568 B

After

Width:  |  Height:  |  Size: 417 B

View File

@@ -0,0 +1,3 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.53324 9.90014H7.18324L6.88324 9.00014H7.63305L6.10211 7.80014H1.78324V4.41577L0.583236 3.47452V8.10014C0.583217 8.59702 0.986361 9.00014 1.46636 9.00014H5.04949L4.74949 9.90014H3.43324C3.1848 9.90014 2.98324 10.1017 2.98324 10.3501C2.98324 10.5986 3.1848 10.8001 3.43324 10.8001H8.51637C8.7648 10.8001 8.96637 10.5986 8.96637 10.3501C8.96637 10.1017 8.79762 9.90014 8.53324 9.90014ZM11.8276 9.99577L10.5507 8.99489C11.0234 8.96789 11.3999 8.57939 11.3999 8.09996V2.09995C11.3999 1.60308 10.9968 1.19995 10.4999 1.19995H1.5168C1.28617 1.19995 1.07786 1.28939 0.918674 1.43208L0.727799 1.29595C0.645299 1.23145 0.547423 1.19995 0.450673 1.19995C0.316986 1.19995 0.184611 1.2592 0.0961106 1.37226C-0.057452 1.56801 -0.023327 1.85095 0.172236 2.00414L11.2724 10.7041C11.4693 10.8579 11.7519 10.8226 11.9041 10.6276C12.0581 10.4321 12.0224 10.149 11.8274 9.99521L11.8276 9.99577ZM10.1832 7.80014H9.00968L2.11905 2.40014H10.1816L10.1832 7.80014Z" fill="#93A1A1"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -1,3 +1,10 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_430_1286)">
<path d="M11.3333 1.33335H9L8.33333 0.666687H6.66667C6.29958 0.666687 6 0.96627 6 1.33335V4.66669C6 5.03377 6.29958 5.33335 6.66667 5.33335H11.3333C11.7004 5.33335 12 5.03377 12 4.66669V2.00002C12 1.63294 11.7 1.33335 11.3333 1.33335ZM11.3333 7.33335H9L8.33333 6.66669H6.66667C6.29958 6.66669 6 6.96627 6 7.33335V10.6667C6 11.0338 6.29958 11.3334 6.66667 11.3334H11.3333C11.7004 11.3334 12 11.0338 12 10.6667V8.00002C12 7.63335 11.7 7.33335 11.3333 7.33335ZM1.33333 1.00002C1.33333 0.815125 1.185 0.666687 1 0.666687H0.333333C0.148438 0.666687 0 0.81502 0 1.00002V9.33335C0 9.70044 0.299583 10 0.666667 10H5.33333V8.66669H1.33333V4.00002H5.33333V2.66669H1.33333V1.00002Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1286">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 790 B

After

Width:  |  Height:  |  Size: 934 B

View File

@@ -1,3 +1,10 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_430_1367)">
<path d="M7.55556 0.888902H6L5.55556 0.444458H4.44444C4.19972 0.444458 4 0.64418 4 0.888902V3.11112C4 3.35585 4.19972 3.55557 4.44444 3.55557H7.55556C7.80028 3.55557 8 3.35585 8 3.11112V1.33335C8 1.08862 7.8 0.888902 7.55556 0.888902ZM7.55556 4.8889H6L5.55556 4.44446H4.44444C4.19972 4.44446 4 4.64418 4 4.8889V7.11112C4 7.35585 4.19972 7.55557 4.44444 7.55557H7.55556C7.80028 7.55557 8 7.35585 8 7.11112V5.33335C8 5.0889 7.8 4.8889 7.55556 4.8889ZM0.888889 0.66668C0.888889 0.543416 0.79 0.444458 0.666667 0.444458H0.222222C0.0989583 0.444458 0 0.543347 0 0.66668V6.22224C0 6.46696 0.199722 6.66668 0.444444 6.66668H3.55556V5.77779H0.888889V2.66668H3.55556V1.77779H0.888889V0.66668Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1367">
<rect width="8" height="8" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 799 B

After

Width:  |  Height:  |  Size: 941 B

View File

@@ -1,6 +1,6 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_614_97)">
<path d="M5 7.62515C5 7.77359 4.9125 7.90796 4.77812 7.96734C4.64219 8.02828 4.47031 8.00327 4.37344 7.90328L3.12344 6.77828C3.04531 6.70796 3 6.6064 3 6.50015C3 6.3939 3.04531 6.29234 3.12344 6.22203L4.37344 5.09703C4.47031 4.99703 4.64219 4.97203 4.77812 5.03296C4.9125 5.09234 5 5.22671 5 5.37515V6.00015H5.25C5.80156 6.00015 6.25 5.55171 6.25 5.00015V2.39546C5.80781 2.18921 5.5 1.76265 5.5 1.25015C5.5 0.559838 6.05937 0.000150232 6.75 0.000150232C7.44063 0.000134607 8 0.559838 8 1.25015C8 1.76265 7.69219 2.18921 7.25 2.39546V5.00015C7.25 6.10484 6.35469 7.00015 5.25 7.00015H5V7.62515ZM7.125 1.23609C7.125 1.04296 6.95781 0.861088 6.75 0.861088C6.54219 0.861088 6.375 1.04296 6.375 1.23609C6.375 1.45718 6.54219 1.61109 6.75 1.61109C6.95781 1.61109 7.125 1.45718 7.125 1.23609ZM3 0.37515C3 0.227025 3.0875 0.0928065 3.22187 0.032494C3.35781 -0.0278185 3.51562 -0.00281852 3.62656 0.096244L4.87656 1.22123C4.95469 1.29232 5 1.39373 5 1.49998C5 1.60623 4.95469 1.70779 4.87656 1.7781L3.62656 2.9031C3.51562 3.0031 3.35781 3.0281 3.22187 2.96717C3.0875 2.90779 3 2.77342 3 2.62498V1.99998H2.75C2.19844 1.99998 1.75 2.44842 1.75 2.99998V5.60467C2.19219 5.79685 2.5 6.23748 2.5 6.74998C2.5 7.4406 1.94062 7.99998 1.25 7.99998C0.559687 7.99998 0 7.4406 0 6.74998C0 6.23748 0.308594 5.79685 0.75 5.60467V2.99998C0.75 1.89529 1.64531 0.999978 2.75 0.999978H3V0.374978V0.37515ZM0.875 6.75015C0.875 6.95796 1.04297 7.12515 1.25 7.12515C1.45703 7.12515 1.625 6.95796 1.625 6.75015C1.625 6.54234 1.45703 6.37515 1.25 6.37515C1.04297 6.37515 0.875 6.54234 0.875 6.75015Z" fill="white"/>
<path d="M5 7.62515C5 7.77359 4.9125 7.90796 4.77812 7.96734C4.64219 8.02828 4.47031 8.00328 4.37344 7.90328L3.12344 6.77828C3.04531 6.70796 3 6.6064 3 6.50015C3 6.3939 3.04531 6.29234 3.12344 6.22203L4.37344 5.09703C4.47031 4.99703 4.64219 4.97203 4.77812 5.03296C4.9125 5.09234 5 5.22671 5 5.37515V6.00015H5.25C5.80156 6.00015 6.25 5.55171 6.25 5.00015V2.39546C5.80781 2.18921 5.5 1.76265 5.5 1.25015C5.5 0.559838 6.05937 0.000150232 6.75 0.000150232C7.44063 0.000134607 8 0.559838 8 1.25015C8 1.76265 7.69219 2.18921 7.25 2.39546V5.00015C7.25 6.10484 6.35469 7.00015 5.25 7.00015H5V7.62515ZM7.125 1.23609C7.125 1.04296 6.95781 0.861088 6.75 0.861088C6.54219 0.861088 6.375 1.04296 6.375 1.23609C6.375 1.45718 6.54219 1.61109 6.75 1.61109C6.95781 1.61109 7.125 1.45718 7.125 1.23609ZM3 0.37515C3 0.227025 3.0875 0.0928065 3.22187 0.032494C3.35781 -0.0278185 3.51563 -0.00281852 3.62656 0.096244L4.87656 1.22123C4.95469 1.29232 5 1.39373 5 1.49998C5 1.60623 4.95469 1.70779 4.87656 1.7781L3.62656 2.9031C3.51563 3.0031 3.35781 3.0281 3.22187 2.96717C3.0875 2.90779 3 2.77342 3 2.62498V1.99998H2.75C2.19844 1.99998 1.75 2.44842 1.75 2.99998V5.60467C2.19219 5.79685 2.5 6.23748 2.5 6.74998C2.5 7.4406 1.94063 7.99998 1.25 7.99998C0.559687 7.99998 0 7.4406 0 6.74998C0 6.23748 0.308594 5.79685 0.75 5.60467V2.99998C0.75 1.89529 1.64531 0.999978 2.75 0.999978H3V0.374978V0.37515ZM0.875 6.75015C0.875 6.95796 1.04297 7.12515 1.25 7.12515C1.45703 7.12515 1.625 6.95796 1.625 6.75015C1.625 6.54234 1.45703 6.37515 1.25 6.37515C1.04297 6.37515 0.875 6.54234 0.875 6.75015Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_614_97">

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -1,3 +1,10 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.8167 11.0391L8.67607 7.89844C9.35576 7.06641 9.73076 6.01875 9.73076 4.875C9.73076 2.18203 7.54802 0 4.85576 0C2.16349 0 0.00161743 2.18273 0.00161743 4.875C0.00161743 7.56727 2.18412 9.75 4.85552 9.75C5.99904 9.75 7.0481 9.35367 7.87896 8.69438L11.0196 11.835C11.1508 11.9461 11.2961 12 11.4391 12C11.5821 12 11.7269 11.9449 11.8369 11.835C12.0555 11.6154 12.0555 11.2591 11.8165 11.0388L11.8167 11.0391ZM1.12685 4.875C1.12685 2.80734 2.8092 1.125 4.87685 1.125C6.94451 1.125 8.62685 2.80734 8.62685 4.875C8.62685 6.94266 6.94451 8.625 4.87685 8.625C2.8092 8.625 1.12685 6.94219 1.12685 4.875Z" fill="white"/>
<g clip-path="url(#clip0_430_1288)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.40624 7.54167C6.77901 8.13568 5.93205 8.5 5 8.5C3.067 8.5 1.5 6.933 1.5 5C1.5 3.067 3.067 1.5 5 1.5C6.933 1.5 8.5 3.067 8.5 5C8.5 5.93205 8.13568 6.77901 7.54167 7.40624C7.51667 7.42558 7.49261 7.44673 7.46967 7.46967C7.44673 7.49261 7.42558 7.51667 7.40624 7.54167ZM7.96544 9.0261C7.13578 9.63821 6.11014 10 5 10C2.23858 10 0 7.76142 0 5C0 2.23858 2.23858 0 5 0C7.76142 0 10 2.23858 10 5C10 6.11014 9.63821 7.13578 9.0261 7.96544L11.5303 10.4697C11.8232 10.7626 11.8232 11.2374 11.5303 11.5303C11.2374 11.8232 10.7626 11.8232 10.4697 11.5303L7.96544 9.0261Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1288">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 727 B

After

Width:  |  Height:  |  Size: 874 B

View File

@@ -1,3 +1,10 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.87779 7.35938L5.78404 5.26562C6.23716 4.71094 6.48716 4.0125 6.48716 3.25C6.48716 1.45469 5.03201 0 3.23716 0C1.44232 0 0.00106812 1.45516 0.00106812 3.25C0.00106812 5.04484 1.45607 6.5 3.23701 6.5C3.99935 6.5 4.69873 6.23578 5.25263 5.79625L7.34638 7.89C7.43388 7.96406 7.53076 8 7.62607 8C7.72138 8 7.81794 7.96328 7.89123 7.89C8.03701 7.74359 8.03701 7.50609 7.87763 7.35922L7.87779 7.35938ZM0.751224 3.25C0.751224 1.87156 1.87279 0.75 3.25122 0.75C4.62966 0.75 5.75122 1.87156 5.75122 3.25C5.75122 4.62844 4.62966 5.75 3.25122 5.75C1.87279 5.75 0.751224 4.62813 0.751224 3.25Z" fill="white"/>
<g clip-path="url(#clip0_430_1369)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.16734 5.87445C4.62987 6.26778 3.96705 6.5 3.25 6.5C1.45507 6.5 0 5.04493 0 3.25C0 1.45507 1.45507 0 3.25 0C5.04493 0 6.5 1.45507 6.5 3.25C6.5 3.96705 6.26778 4.62987 5.87445 5.16734L7.85355 7.14645C8.04882 7.34171 8.04882 7.65829 7.85355 7.85355C7.65829 8.04882 7.34171 8.04882 7.14645 7.85355L5.16734 5.87445ZM5.5 3.25C5.5 4.49264 4.49264 5.5 3.25 5.5C2.00736 5.5 1 4.49264 1 3.25C1 2.00736 2.00736 1 3.25 1C4.49264 1 5.5 2.00736 5.5 3.25Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1369">
<rect width="8" height="8" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 708 B

After

Width:  |  Height:  |  Size: 750 B

View File

@@ -1,6 +1,6 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_609_69)">
<path d="M2.77187 4.52188L0.999998 6.29375V5.50001C0.999998 5.2236 0.776405 5.00001 0.499999 5.00001C0.223593 5.00001 0 5.2236 0 5.50001V7.5C0 7.565 0.013125 7.62985 0.0385155 7.69094C0.0891405 7.81328 0.186484 7.91078 0.308984 7.96141C0.370077 7.9875 0.434921 8 0.499921 8H2.49992C2.77632 8 2.99992 7.77641 2.99992 7.5C2.99992 7.2236 2.77632 7 2.49992 7H1.70773L3.4796 5.22813C3.67492 5.03282 3.67492 4.71641 3.4796 4.5211C3.28429 4.32579 2.9671 4.32657 2.77179 4.52188H2.77187ZM7.96092 0.309078C7.91014 0.186578 7.8128 0.089078 7.6903 0.038453C7.62967 0.0131406 7.56561 0 7.49999 0H5.49999C5.22358 0 4.99999 0.223593 4.99999 0.499999C4.99999 0.776405 5.22358 0.999998 5.49999 0.999998H6.29296L4.52109 2.77187C4.32577 2.96718 4.32577 3.28359 4.52109 3.4789C4.71624 3.67406 5.03265 3.67437 5.22812 3.4789L6.99999 1.70782V2.50001C6.99999 2.77642 7.22358 3.00001 7.49999 3.00001C7.77639 3.00001 7.99998 2.77642 7.99998 2.50001V0.500015C7.99998 0.435015 7.98748 0.370171 7.96092 0.309078Z" fill="white"/>
<path d="M2.77188 4.52188L1.00001 6.29375V5.50001C1.00001 5.2236 0.776412 5.00001 0.500007 5.00001C0.223601 5.00001 7.62939e-06 5.2236 7.62939e-06 5.50001V7.5C7.62939e-06 7.565 0.0131326 7.62984 0.0385232 7.69094C0.0891481 7.81328 0.186492 7.91078 0.308991 7.96141C0.370085 7.9875 0.434929 8 0.499929 8H2.49992C2.77633 8 2.99992 7.77641 2.99992 7.5C2.99992 7.2236 2.77633 7 2.49992 7H1.70774L3.47961 5.22813C3.67492 5.03282 3.67492 4.71641 3.47961 4.5211C3.2843 4.32579 2.96711 4.32657 2.7718 4.52188H2.77188ZM7.96093 0.309078C7.91015 0.186578 7.81281 0.089078 7.69031 0.0384531C7.62968 0.0131406 7.56562 0 7.49999 0H5.5C5.22359 0 5 0.223593 5 0.499999C5 0.776405 5.22359 0.999998 5.5 0.999998H6.29296L4.52109 2.77187C4.32578 2.96718 4.32578 3.28359 4.52109 3.4789C4.71625 3.67406 5.03265 3.67437 5.22812 3.4789L6.99999 1.70782V2.50001C6.99999 2.77642 7.22359 3.00001 7.49999 3.00001C7.7764 3.00001 7.99999 2.77642 7.99999 2.50001V0.500015C7.99999 0.435015 7.98749 0.370171 7.96093 0.309078Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_609_69">

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -1,6 +1,6 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_609_75)">
<path d="M0.854041 7.85284L2.75022 5.95775V6.74984C2.75022 7.02622 2.97379 7.24978 3.25017 7.24978C3.52654 7.24978 3.75011 7.02622 3.75011 6.74984V4.75008C3.75011 4.68493 3.73683 4.62009 3.71152 4.55916C3.6609 4.43605 3.56404 4.33919 3.44061 4.28919C3.37968 4.26264 3.31563 4.25014 3.25001 4.25014H1.25024C0.97387 4.25014 0.750303 4.4737 0.750303 4.75008C0.750303 5.02645 0.97387 5.25002 1.25024 5.25002H2.04312L0.146467 7.14667C-0.0488224 7.34196 -0.0488224 7.65833 0.146467 7.85362C0.341757 8.04891 0.658595 8.04813 0.853884 7.85284H0.854041ZM4.28911 3.44086C4.33973 3.56334 4.43706 3.66083 4.5597 3.71145C4.62032 3.7377 4.68437 3.7502 4.74999 3.7502H6.74976C7.02613 3.7502 7.2497 3.52663 7.2497 3.25025C7.2497 2.97388 7.02613 2.75031 6.74976 2.75031H5.95688L7.85353 0.85366C8.04882 0.65837 8.04882 0.342001 7.85353 0.146711C7.6584 -0.048422 7.34203 -0.0487345 7.14658 0.146711L5.24993 2.04415V1.25049C5.24993 0.974114 5.02636 0.750547 4.74999 0.750547C4.47362 0.750547 4.25005 0.974114 4.25005 1.25049V3.23619C4.25005 3.31587 4.26255 3.37993 4.28911 3.44086Z" fill="white"/>
<path d="M0.854041 7.85284L2.75022 5.95775V6.74984C2.75022 7.02622 2.97379 7.24979 3.25017 7.24979C3.52654 7.24979 3.75011 7.02622 3.75011 6.74984V4.75008C3.75011 4.68493 3.73683 4.62009 3.71152 4.55916C3.6609 4.43605 3.56404 4.33919 3.44061 4.28919C3.37968 4.26264 3.31563 4.25014 3.25001 4.25014H1.25024C0.97387 4.25014 0.750303 4.4737 0.750303 4.75008C0.750303 5.02645 0.97387 5.25002 1.25024 5.25002H2.04312L0.146467 7.14667C-0.0488224 7.34196 -0.0488224 7.65833 0.146467 7.85362C0.341757 8.04891 0.658595 8.04813 0.853884 7.85284H0.854041ZM4.28911 3.44086C4.33973 3.56334 4.43706 3.66083 4.5597 3.71145C4.62032 3.7377 4.68437 3.7502 4.74999 3.7502H6.74976C7.02613 3.7502 7.2497 3.52663 7.2497 3.25025C7.2497 2.97388 7.02613 2.75031 6.74976 2.75031H5.95688L7.85353 0.85366C8.04882 0.65837 8.04882 0.342001 7.85353 0.146711C7.6584 -0.048422 7.34203 -0.0487345 7.14658 0.146711L5.24993 2.04415V1.25049C5.24993 0.974114 5.02636 0.750547 4.74999 0.750547C4.47362 0.750547 4.25005 0.974114 4.25005 1.25049V3.23619C4.25005 3.31587 4.26255 3.37993 4.28911 3.44086Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_609_75">

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1,3 +1,10 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6 2.5V9.5M2.5 6H9.5" stroke="white" stroke-linecap="round"/>
<g clip-path="url(#clip0_519_280)">
<path d="M6 2.5V9.5M2.5 6H9.5" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
</g>
<defs>
<clipPath id="clip0_519_280">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 174 B

After

Width:  |  Height:  |  Size: 335 B

View File

@@ -1,3 +1,10 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8 2V14M2 8H14" stroke="white" stroke-width="1.71429" stroke-linecap="round"/>
<g clip-path="url(#clip0_702_228)">
<path d="M8.00001 3.33331V12.6666M3.33334 7.99998H12.6667" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
</g>
<defs>
<clipPath id="clip0_702_228">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 191 B

After

Width:  |  Height:  |  Size: 363 B

View File

@@ -1,3 +1,10 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4 1.5V6.5M1.5 4H6.5" stroke="white" stroke-linecap="round"/>
<g clip-path="url(#clip0_519_287)">
<path d="M4 1V7M1 4H7" stroke="white" stroke-linecap="round"/>
</g>
<defs>
<clipPath id="clip0_519_287">
<rect width="8" height="8" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 170 B

After

Width:  |  Height:  |  Size: 302 B

View File

@@ -1,5 +1,12 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_430_1301)">
<path d="M11 1H6V11H11V1Z" fill="white" fill-opacity="0.2"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.1818 1C1.51237 1 1.04544 1.48778 1.04544 2V10C1.04544 10.5122 1.51237 11 2.1818 11H9.81817C10.4876 11 10.9545 10.5122 10.9545 10V2C10.9545 1.48778 10.4876 1 9.81817 1H2.1818ZM0.0454407 2C0.0454407 0.855367 1.04377 0 2.1818 0H9.81817C10.9562 0 11.9545 0.855367 11.9545 2V10C11.9545 11.1446 10.9562 12 9.81817 12H2.1818C1.04377 12 0.0454407 11.1446 0.0454407 10V2Z" fill="white"/>
<path d="M6.09091 1H5V11H6.09091V1Z" fill="white"/>
<path d="M6 1H5V11H6V1Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1301">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 647 B

After

Width:  |  Height:  |  Size: 779 B

View File

@@ -1,3 +1,10 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_430_1295)">
<path d="M0 2.25C0 1.42148 0.67148 0.75 1.5 0.75H10.5C11.3273 0.75 12 1.42148 12 2.25V9.75C12 10.5773 11.3273 11.25 10.5 11.25H1.5C0.67148 11.25 0 10.5773 0 9.75V2.25ZM2.39766 3.55781C2.18789 3.7875 2.20336 4.14141 2.43281 4.35234L4.23047 6L2.43281 7.64766C2.20336 7.85859 2.18789 8.2125 2.39766 8.44219C2.60859 8.65078 2.9625 8.68594 3.19219 8.47734L5.44219 6.41484C5.55937 6.30703 5.625 6.15703 5.625 5.97891C5.625 5.84297 5.55937 5.69297 5.44219 5.58516L3.19219 3.52266C2.9625 3.31406 2.60859 3.32813 2.39766 3.55781ZM5.8125 7.875C5.50078 7.875 5.25 8.12578 5.25 8.4375C5.25 8.74922 5.50078 9 5.8125 9H9.1875C9.4992 9 9.75 8.74922 9.75 8.4375C9.75 8.12578 9.4992 7.875 9.1875 7.875H5.8125Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1295">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 812 B

After

Width:  |  Height:  |  Size: 956 B

View File

@@ -1,3 +1,10 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_430_1381)">
<path d="M0 1.5C0 0.947653 0.447653 0.5 1 0.5H7C7.55153 0.5 8 0.947653 8 1.5V6.5C8 7.05153 7.55153 7.5 7 7.5H1C0.447653 7.5 0 7.05153 0 6.5V1.5ZM1.59844 2.37187C1.45859 2.525 1.46891 2.76094 1.62187 2.90156L2.82031 4L1.62187 5.09844C1.46891 5.23906 1.45859 5.475 1.59844 5.62813C1.73906 5.76719 1.975 5.79063 2.12813 5.65156L3.62813 4.27656C3.70625 4.20469 3.75 4.10469 3.75 3.98594C3.75 3.89531 3.70625 3.79531 3.62813 3.72344L2.12813 2.34844C1.975 2.20937 1.73906 2.21875 1.59844 2.37187ZM3.875 5.25C3.66719 5.25 3.5 5.41719 3.5 5.625C3.5 5.83281 3.66719 6 3.875 6H6.125C6.3328 6 6.5 5.83281 6.5 5.625C6.5 5.41719 6.3328 5.25 6.125 5.25H3.875Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1381">
<rect width="8" height="8" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 761 B

After

Width:  |  Height:  |  Size: 903 B

View File

@@ -1,3 +1,10 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_430_1297)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 11.625H0V9.375L5.25 0.375H6.75L12 9.375V11.625ZM5.25 3.375H6.75V7.125H5.25V3.375ZM5.25 8.625H6.75V10.125H5.25V8.625Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1297">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 289 B

After

Width:  |  Height:  |  Size: 433 B

View File

@@ -1,3 +1,10 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_430_1371)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 7.75H0V6.25L3.5 0.25H4.5L8 6.25V7.75ZM3.5 2.25H4.5V4.75H3.5V2.25ZM3.5 5.75H4.5V6.75H3.5V5.75Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1371">
<rect width="8" height="8" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 261 B

After

Width:  |  Height:  |  Size: 403 B

View File

@@ -1,3 +1,10 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_430_1383)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.75 1C5.33579 1 5 1.33579 5 1.75V3H6.5V8H0.5V3H4V1.75C4 0.783502 4.7835 0 5.75 0C6.7165 0 7.5 0.783502 7.5 1.75V2H6.5V1.75C6.5 1.33579 6.16421 1 5.75 1ZM4.5 5H2.5V6H4.5V5Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1383">
<rect width="8" height="8" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 338 B

After

Width:  |  Height:  |  Size: 480 B

View File

@@ -1,3 +1,10 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_430_1299)">
<path d="M6 0C2.68594 0 0 2.68594 0 6C0 9.31406 2.68594 12 6 12C9.31406 12 12 9.31406 12 6C12 2.68594 9.31406 0 6 0ZM6 3C6.93211 3 7.6875 3.75563 7.6875 4.6875C7.6875 5.61937 6.93281 6.375 6 6.375C5.06813 6.375 4.3125 5.61937 4.3125 4.6875C4.3125 3.75563 5.06719 3 6 3ZM6 10.5C4.75945 10.5 3.63516 9.99539 2.81953 9.1807C3.19922 8.20078 4.13672 7.5 5.25 7.5H6.75C7.86422 7.5 8.80172 8.20031 9.18047 9.1807C8.36484 9.99609 7.23984 10.5 6 10.5Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1299">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 562 B

After

Width:  |  Height:  |  Size: 706 B

View File

@@ -1,3 +1,10 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4 0C1.79063 0 0 1.79063 0 4C0 6.20937 1.79063 8 4 8C6.20937 8 8 6.20937 8 4C8 1.79063 6.20937 0 4 0ZM4 2C4.62141 2 5.125 2.50375 5.125 3.125C5.125 3.74625 4.62187 4.25 4 4.25C3.37875 4.25 2.875 3.74625 2.875 3.125C2.875 2.50375 3.37812 2 4 2ZM4 7C3.17297 7 2.42344 6.66359 1.87969 6.12047C2.13281 5.46719 2.75781 5 3.5 5H4.5C5.24281 5 5.86781 5.46688 6.12031 6.12047C5.57656 6.66406 4.82656 7 4 7Z" fill="white"/>
<g clip-path="url(#clip0_430_1382)">
<path d="M4 0C1.79063 0 0 1.79063 0 4C0 6.20937 1.79063 8 4 8C6.20937 8 8 6.20937 8 4C8 1.79063 6.20937 0 4 0ZM4 2C4.62141 2 5.125 2.50375 5.125 3.125C5.125 3.74625 4.62187 4.25 4 4.25C3.37875 4.25 2.875 3.74625 2.875 3.125C2.875 2.50375 3.37813 2 4 2ZM4 7C3.17297 7 2.42344 6.66359 1.87969 6.12047C2.13281 5.46719 2.75781 5 3.5 5H4.5C5.24281 5 5.86781 5.46687 6.12031 6.12047C5.57656 6.66406 4.82656 7 4 7Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1382">
<rect width="8" height="8" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 523 B

After

Width:  |  Height:  |  Size: 665 B

View File

@@ -1,3 +1,3 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4.2 6.00001C5.52563 6.00001 6.6 4.92545 6.6 3.60001C6.6 2.27457 5.52563 1.20001 4.2 1.20001C2.87438 1.20001 1.8 2.27457 1.8 3.60001C1.8 4.92545 2.87438 6.00001 4.2 6.00001ZM5.15063 6.90001H3.24938C1.45444 6.90001 0 8.35501 0 10.1494C0 10.5094 0.291 10.8 0.649875 10.8H7.74937C8.10938 10.8 8.4 10.5094 8.4 10.1494C8.4 8.35501 6.945 6.90001 5.15063 6.90001ZM8.98313 7.20001H7.59844C8.46 7.90689 9 8.96439 9 10.1494C9 10.3894 8.92875 10.6106 8.8125 10.8H11.4C11.7319 10.8 12 10.53 12 10.1831C12 8.54251 10.6575 7.20001 8.98313 7.20001ZM8.1 6.00001C9.26063 6.00001 10.2 5.06064 10.2 3.90001C10.2 2.73939 9.26063 1.80001 8.1 1.80001C7.62919 1.80001 7.19925 1.96042 6.849 2.22207C7.065 2.63682 7.2 3.10126 7.2 3.60001C7.2 4.26601 6.97631 4.87764 6.60769 5.37582C6.98813 5.76001 7.515 6.00001 8.1 6.00001Z" fill="white"/>
<path d="M4.2 6.00001C5.52563 6.00001 6.6 4.92545 6.6 3.60001C6.6 2.27457 5.52563 1.20001 4.2 1.20001C2.87438 1.20001 1.8 2.27457 1.8 3.60001C1.8 4.92545 2.87438 6.00001 4.2 6.00001ZM5.15063 6.90001H3.24938C1.45444 6.90001 0 8.35501 0 10.1494C0 10.5094 0.291 10.8 0.649875 10.8H7.74938C8.10938 10.8 8.4 10.5094 8.4 10.1494C8.4 8.35501 6.945 6.90001 5.15063 6.90001ZM8.98313 7.20001H7.59844C8.46 7.90689 9 8.96439 9 10.1494C9 10.3894 8.92875 10.6106 8.8125 10.8H11.4C11.7319 10.8 12 10.53 12 10.1831C12 8.54251 10.6575 7.20001 8.98313 7.20001ZM8.1 6.00001C9.26063 6.00001 10.2 5.06064 10.2 3.90001C10.2 2.73939 9.26063 1.80001 8.1 1.80001C7.62919 1.80001 7.19925 1.96042 6.849 2.22207C7.065 2.63682 7.2 3.10126 7.2 3.60001C7.2 4.26601 6.97631 4.87764 6.60769 5.37582C6.98813 5.76001 7.515 6.00001 8.1 6.00001Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 928 B

After

Width:  |  Height:  |  Size: 928 B

View File

@@ -1,3 +1,10 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.8 3.99999C3.68375 3.99999 4.4 3.28361 4.4 2.39999C4.4 1.51636 3.68375 0.799988 2.8 0.799988C1.91625 0.799988 1.2 1.51636 1.2 2.39999C1.2 3.28361 1.91625 3.99999 2.8 3.99999ZM3.43375 4.59999H2.16625C0.969625 4.59999 0 5.56999 0 6.76624C0 7.00624 0.194 7.19999 0.43325 7.19999H5.16625C5.40625 7.19999 5.6 7.00624 5.6 6.76624C5.6 5.56999 4.63 4.59999 3.43375 4.59999ZM5.98875 4.79999H5.06563C5.64 5.27124 6 5.97624 6 6.76624C6 6.92624 5.9525 7.07374 5.875 7.19999H7.6C7.82125 7.19999 8 7.01999 8 6.78874C8 5.69499 7.105 4.79999 5.98875 4.79999ZM5.4 3.99999C6.17375 3.99999 6.8 3.37374 6.8 2.59999C6.8 1.82624 6.17375 1.19999 5.4 1.19999C5.08612 1.19999 4.7995 1.30693 4.566 1.48136C4.71 1.75786 4.8 2.06749 4.8 2.39999C4.8 2.84399 4.65088 3.25174 4.40513 3.58386C4.65875 3.83999 5.01 3.99999 5.4 3.99999Z" fill="white"/>
<g clip-path="url(#clip0_430_1375)">
<path d="M2.8 3.99999C3.68375 3.99999 4.4 3.28361 4.4 2.39999C4.4 1.51636 3.68375 0.799988 2.8 0.799988C1.91625 0.799988 1.2 1.51636 1.2 2.39999C1.2 3.28361 1.91625 3.99999 2.8 3.99999ZM3.43375 4.59999H2.16625C0.969625 4.59999 0 5.56999 0 6.76624C0 7.00624 0.194 7.19999 0.43325 7.19999H5.16625C5.40625 7.19999 5.6 7.00624 5.6 6.76624C5.6 5.56999 4.63 4.59999 3.43375 4.59999ZM5.98875 4.79999H5.06563C5.64 5.27124 6 5.97624 6 6.76624C6 6.92624 5.9525 7.07374 5.875 7.19999H7.6C7.82125 7.19999 8 7.01999 8 6.78874C8 5.69499 7.105 4.79999 5.98875 4.79999ZM5.4 3.99999C6.17375 3.99999 6.8 3.37374 6.8 2.59999C6.8 1.82624 6.17375 1.19999 5.4 1.19999C5.08613 1.19999 4.7995 1.30693 4.566 1.48136C4.71 1.75786 4.8 2.06749 4.8 2.39999C4.8 2.84399 4.65088 3.25174 4.40513 3.58386C4.65875 3.83999 5.01 3.99999 5.4 3.99999Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1375">
<rect width="8" height="8" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 929 B

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -1,3 +1,10 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_430_1373)">
<path d="M2.8 3.99999C3.68375 3.99999 4.4 3.28361 4.4 2.39999C4.4 1.51636 3.68375 0.799988 2.8 0.799988C1.91625 0.799988 1.2 1.51636 1.2 2.39999C1.2 3.28361 1.91625 3.99999 2.8 3.99999ZM3.43375 4.59999H2.16625C0.970125 4.59999 0 5.56999 0 6.76624C0 7.00624 0.194 7.19999 0.43325 7.19999H5.167C5.40625 7.19999 5.6 7.00624 5.6 6.76624C5.6 5.56999 4.63 4.59999 3.43375 4.59999ZM7.7 3.29999H7.1V2.69999C7.1 2.53499 6.96625 2.39999 6.8 2.39999C6.63375 2.39999 6.5 2.53436 6.5 2.69999V3.29999H5.9C5.735 3.29999 5.6 3.43499 5.6 3.59999C5.6 3.76499 5.73438 3.89999 5.9 3.89999H6.5V4.49999C6.5 4.66624 6.635 4.79999 6.8 4.79999C6.965 4.79999 7.1 4.66561 7.1 4.49999V3.89999H7.7C7.86625 3.89999 8 3.76624 8 3.59999C8 3.43374 7.86625 3.29999 7.7 3.29999Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_430_1373">
<rect width="8" height="8" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 859 B

After

Width:  |  Height:  |  Size: 1001 B

View File

@@ -1,3 +1,10 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.71108 6L0 2.28892L2.28892 0L6 3.71108L9.71108 0L12 2.28892L8.28892 6L12 9.71108L9.71108 12L6 8.28892L2.28892 12L0 9.71108L3.71108 6Z" fill="white"/>
<g clip-path="url(#clip0_430_1296)">
<path d="M9.5 2.5L6 6M2.5 9.5L6 6M2.5 2.5L6 6M6 6L9.5 9.5" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
</g>
<defs>
<clipPath id="clip0_430_1296">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 304 B

After

Width:  |  Height:  |  Size: 365 B

View File

@@ -1,3 +1,10 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.32959 8L1 3.67041L3.67041 1L8 5.32959L12.3296 1L15 3.67041L10.6704 8L15 12.3296L12.3296 15L8 10.6704L3.67041 15L1 12.3296L5.32959 8Z" fill="white"/>
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_702_229)">
<path d="M11.875 3.125L7.5 7.5M3.125 11.875L7.5 7.5M3.125 3.125L7.5 7.5M7.5 7.5L11.875 11.875" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
</g>
<defs>
<clipPath id="clip0_702_229">
<rect width="15" height="15" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 304 B

After

Width:  |  Height:  |  Size: 399 B

View File

@@ -1,3 +1,10 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.47405 4L0 1.52595L1.52595 0L4 2.47405L6.47405 0L8 1.52595L5.52595 4L8 6.47405L6.47405 8L4 5.52595L1.52595 8L0 6.47405L2.47405 4Z" fill="white"/>
<g clip-path="url(#clip0_430_1379)">
<path d="M6.49999 1.49999L1.49997 6.5M1.49998 1.50002L6.49999 6.50004" stroke="white" stroke-linecap="round"/>
</g>
<defs>
<clipPath id="clip0_430_1379">
<rect width="8" height="8" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 296 B

After

Width:  |  Height:  |  Size: 352 B

View File

@@ -1,3 +0,0 @@
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.76433 6.63513C8.0768 6.9476 8.0768 7.4538 7.76433 7.76627C7.60935 7.92251 7.40437 8 7.19939 8C6.99441 8 6.78992 7.92188 6.63394 7.76565L3.99969 5.13264L1.36568 7.7649C1.20945 7.92238 1.00472 7.99988 0.799986 7.99988C0.595255 7.99988 0.390774 7.92238 0.234414 7.7649C-0.0780566 7.45243 -0.0780566 6.94622 0.234414 6.63375L2.86917 3.999L0.234414 1.3655C-0.0780566 1.05303 -0.0780566 0.546824 0.234414 0.234353C0.546885 -0.0781177 1.05309 -0.0781177 1.36556 0.234353L3.99969 2.87023L6.63444 0.235478C6.94691 -0.0769928 7.45311 -0.0769928 7.76558 0.235478C8.07805 0.547949 8.07805 1.05415 7.76558 1.36662L5.13083 4.00138L7.76433 6.63488V6.63513Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 769 B

View File

@@ -1,4 +0,0 @@
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M5 11C5 14.3137 7.68629 17 11 17C14.3137 17 17 14.3137 17 11C17 7.68629 14.3137 5 11 5C7.68629 5 5 7.68629 5 11ZM11 3C6.58172 3 3 6.58172 3 11C3 15.4183 6.58172 19 11 19C15.4183 19 19 15.4183 19 11C19 6.58172 15.4183 3 11 3Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.09092 8.09088H14.6364L10.5511 12.4545H12.4546L13.9091 13.9091H7.36365L11.7273 9.54543H9.54547L8.09092 8.09088Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 571 B

View File

@@ -3,8 +3,12 @@
{
"bindings": {
"up": "menu::SelectPrev",
"pageup": "menu::SelectFirst",
"shift-pageup": "menu::SelectFirst",
"ctrl-p": "menu::SelectPrev",
"down": "menu::SelectNext",
"pagedown": "menu::SelectLast",
"shift-pagedown": "menu::SelectFirst",
"ctrl-n": "menu::SelectNext",
"cmd-up": "menu::SelectFirst",
"cmd-down": "menu::SelectLast",
@@ -60,13 +64,18 @@
"cmd-z": "editor::Undo",
"cmd-shift-z": "editor::Redo",
"up": "editor::MoveUp",
"pageup": "editor::PageUp",
"shift-pageup": "editor::MovePageUp",
"down": "editor::MoveDown",
"pagedown": "editor::PageDown",
"shift-pagedown": "editor::MovePageDown",
"left": "editor::MoveLeft",
"right": "editor::MoveRight",
"ctrl-p": "editor::MoveUp",
"ctrl-n": "editor::MoveDown",
"ctrl-b": "editor::MoveLeft",
"ctrl-f": "editor::MoveRight",
"ctrl-l": "editor::CenterScreen",
"alt-left": "editor::MoveToPreviousWordStart",
"alt-b": "editor::MoveToPreviousWordStart",
"alt-right": "editor::MoveToNextWordEnd",
@@ -118,8 +127,18 @@
"stop_at_soft_wraps": true
}
],
"pageup": "editor::PageUp",
"pagedown": "editor::PageDown",
"ctrl-v": [
"editor::MovePageDown",
{
"center_cursor": true
}
],
"alt-v": [
"editor::MovePageUp",
{
"center_cursor": true
}
],
"ctrl-cmd-space": "editor::ShowCharacterPalette"
}
},
@@ -376,13 +395,16 @@
{
"bindings": {
"ctrl-alt-cmd-f": "workspace::FollowNextCollaborator",
"cmd-shift-c": "collab::ToggleCollaborationMenu",
"cmd-alt-i": "zed::DebugElements"
}
},
{
"context": "Editor",
"bindings": {
"alt-enter": "editor::OpenExcerpts"
"alt-enter": "editor::OpenExcerpts",
"cmd-f8": "editor::GoToHunk",
"cmd-shift-f8": "editor::GoToPrevHunk"
}
},
{
@@ -395,7 +417,6 @@
"context": "Workspace",
"bindings": {
"shift-escape": "dock::FocusDock",
"cmd-shift-c": "contacts_panel::ToggleFocus",
"cmd-shift-b": "workspace::ToggleRightSidebar"
}
},
@@ -412,6 +433,12 @@
"shift-escape": "dock::HideDock"
}
},
{
"context": "Pane",
"bindings": {
"cmd-escape": "dock::MoveActiveItemToDock"
}
},
{
"context": "ProjectPanel",
"bindings": {
@@ -451,10 +478,18 @@
"terminal::SendKeystroke",
"up"
],
"pageup": [
"terminal::SendKeystroke",
"pageup"
],
"down": [
"terminal::SendKeystroke",
"down"
],
"pagedown": [
"terminal::SendKeystroke",
"pagedown"
],
"escape": [
"terminal::SendKeystroke",
"escape"

View File

@@ -9,11 +9,10 @@
}
],
"h": "vim::Left",
"backspace": "vim::Left",
"backspace": "vim::Backspace",
"j": "vim::Down",
"k": "vim::Up",
"l": "vim::Right",
"0": "vim::StartOfLine",
"$": "vim::EndOfLine",
"shift-g": "vim::EndOfDocument",
"w": "vim::NextWordStart",
@@ -38,7 +37,60 @@
}
],
"%": "vim::Matching",
"escape": "editor::Cancel"
"escape": "editor::Cancel",
"i": [
"vim::PushOperator",
{
"Object": {
"around": false
}
}
],
"a": [
"vim::PushOperator",
{
"Object": {
"around": true
}
}
],
"0": "vim::StartOfLine", // When no number operator present, use start of line motion
"1": [
"vim::Number",
1
],
"2": [
"vim::Number",
2
],
"3": [
"vim::Number",
3
],
"4": [
"vim::Number",
4
],
"5": [
"vim::Number",
5
],
"6": [
"vim::Number",
6
],
"7": [
"vim::Number",
7
],
"8": [
"vim::Number",
8
],
"9": [
"vim::Number",
9
]
}
},
{
@@ -98,6 +150,15 @@
]
}
},
{
"context": "Editor && vim_operator == n",
"bindings": {
"0": [
"vim::Number",
0
]
}
},
{
"context": "Editor && vim_operator == g",
"bindings": {
@@ -112,13 +173,6 @@
{
"context": "Editor && vim_operator == c",
"bindings": {
"w": "vim::ChangeWord",
"shift-w": [
"vim::ChangeWord",
{
"ignorePunctuation": true
}
],
"c": "vim::CurrentLine"
}
},
@@ -134,9 +188,34 @@
"y": "vim::CurrentLine"
}
},
{
"context": "Editor && VimObject",
"bindings": {
"w": "vim::Word",
"shift-w": [
"vim::Word",
{
"ignorePunctuation": true
}
],
"s": "vim::Sentence",
"'": "vim::Quotes",
"`": "vim::BackQuotes",
"\"": "vim::DoubleQuotes",
"(": "vim::Parentheses",
")": "vim::Parentheses",
"[": "vim::SquareBrackets",
"]": "vim::SquareBrackets",
"{": "vim::CurlyBrackets",
"}": "vim::CurlyBrackets",
"<": "vim::AngleBrackets",
">": "vim::AngleBrackets"
}
},
{
"context": "Editor && vim_mode == visual",
"bindings": {
"u": "editor::Undo",
"c": "vim::VisualChange",
"d": "vim::VisualDelete",
"x": "vim::VisualDelete",

View File

@@ -1,206 +1,230 @@
{
// The name of the Zed theme to use for the UI
"theme": "one-dark",
// The name of a font to use for rendering text in the editor
"buffer_font_family": "Zed Mono",
// The default font size for text in the editor
"buffer_font_size": 15,
// Whether to enable vim modes and key bindings
"vim_mode": false,
// Whether to show the informational hover box when moving the mouse
// over symbols in the editor.
"hover_popover_enabled": true,
// Whether to pop the completions menu while typing in an editor without
// explicitly requesting it.
"show_completions_on_input": true,
// Whether new projects should start out 'online'. Online projects
// appear in the contacts panel under your name, so that your contacts
// can see which projects you are working on. Regardless of this
// setting, projects keep their last online status when you reopen them.
"projects_online_by_default": true,
// Whether to use language servers to provide code intelligence.
"enable_language_server": true,
// When to automatically save edited buffers. This setting can
// take four values.
//
// 1. Never automatically save:
// "autosave": "off",
// 2. Save when changing focus away from the Zed window:
// "autosave": "on_window_change",
// 3. Save when changing focus away from a specific buffer:
// "autosave": "on_focus_change",
// 4. Save when idle for a certain amount of time:
// "autosave": { "after_delay": {"milliseconds": 500} },
"autosave": "off",
// Where to place the dock by default. This setting can take three
// values:
//
// 1. Position the dock attached to the bottom of the workspace
// "default_dock_anchor": "bottom"
// 2. Position the dock to the right of the workspace like a side panel
// "default_dock_anchor": "right"
// 3. Position the dock full screen over the entire workspace"
// "default_dock_anchor": "expanded"
"default_dock_anchor": "right",
// Whether or not to perform a buffer format before saving
"format_on_save": "on",
// How to perform a buffer format. This setting can take two values:
//
// 1. Format code using the current language server:
// "format_on_save": "language_server"
// 2. Format code using an external command:
// "format_on_save": {
// "external": {
// "command": "prettier",
// "arguments": ["--stdin-filepath", "{buffer_path}"]
// }
// The name of the Zed theme to use for the UI
"theme": "One Dark",
// The name of a font to use for rendering text in the editor
"buffer_font_family": "Zed Mono",
// The default font size for text in the editor
"buffer_font_size": 15,
// Whether to enable vim modes and key bindings
"vim_mode": false,
// Whether to show the informational hover box when moving the mouse
// over symbols in the editor.
"hover_popover_enabled": true,
// Whether the cursor blinks in the editor.
"cursor_blink": true,
// Whether to pop the completions menu while typing in an editor without
// explicitly requesting it.
"show_completions_on_input": true,
// Whether new projects should start out 'online'. Online projects
// appear in the contacts panel under your name, so that your contacts
// can see which projects you are working on. Regardless of this
// setting, projects keep their last online status when you reopen them.
"projects_online_by_default": true,
// Whether to use language servers to provide code intelligence.
"enable_language_server": true,
// When to automatically save edited buffers. This setting can
// take four values.
//
// 1. Never automatically save:
// "autosave": "off",
// 2. Save when changing focus away from the Zed window:
// "autosave": "on_window_change",
// 3. Save when changing focus away from a specific buffer:
// "autosave": "on_focus_change",
// 4. Save when idle for a certain amount of time:
// "autosave": { "after_delay": {"milliseconds": 500} },
"autosave": "off",
// Where to place the dock by default. This setting can take three
// values:
//
// 1. Position the dock attached to the bottom of the workspace
// "default_dock_anchor": "bottom"
// 2. Position the dock to the right of the workspace like a side panel
// "default_dock_anchor": "right"
// 3. Position the dock full screen over the entire workspace"
// "default_dock_anchor": "expanded"
"default_dock_anchor": "right",
// Whether or not to perform a buffer format before saving
"format_on_save": "on",
// How to perform a buffer format. This setting can take two values:
//
// 1. Format code using the current language server:
// "format_on_save": "language_server"
// 2. Format code using an external command:
// "format_on_save": {
// "external": {
// "command": "prettier",
// "arguments": ["--stdin-filepath", "{buffer_path}"]
// }
// }
"formatter": "language_server",
// How to soft-wrap long lines of text. This setting can take
// three values:
//
// 1. Do not soft wrap.
// "soft_wrap": "none",
// 2. Soft wrap lines that overflow the editor:
// "soft_wrap": "editor_width",
// 3. Soft wrap lines at the preferred line length
// "soft_wrap": "preferred_line_length",
"soft_wrap": "none",
// The column at which to soft-wrap lines, for buffers where soft-wrap
// is enabled.
"preferred_line_length": 80,
// Whether to indent lines using tab characters, as opposed to multiple
// spaces.
"hard_tabs": false,
// How many columns a tab should occupy.
"tab_size": 4,
// Git gutter behavior configuration.
"git": {
// Control whether the git gutter is shown. May take 2 values:
// 1. Show the gutter
// "git_gutter": "tracked_files"
// 2. Hide the gutter
// "git_gutter": "hide"
"git_gutter": "tracked_files"
},
// Settings specific to journaling
"journal": {
// The path of the directory where journal entries are stored
"path": "~",
// What format to display the hours in
// May take 2 values:
// 1. hour12
// 2. hour24
"hour_format": "hour12"
},
// Settings specific to the terminal
"terminal": {
// What shell to use when opening a terminal. May take 3 values:
// 1. Use the system's default terminal configuration (e.g. $TERM).
// "shell": "system"
// 2. A program:
// "shell": {
// "program": "sh"
// }
// 3. A program with arguments:
// "shell": {
// "with_arguments": {
// "program": "/bin/bash",
// "arguments": ["--login"]
// }
// }
"formatter": "language_server",
// How to soft-wrap long lines of text. This setting can take
// three values:
"shell": "system",
// What working directory to use when launching the terminal.
// May take 4 values:
// 1. Use the current file's project directory. Will Fallback to the
// first project directory strategy if unsuccessful
// "working_directory": "current_project_directory"
// 2. Use the first project in this workspace's directory
// "working_directory": "first_project_directory"
// 3. Always use this platform's home directory (if we can find it)
// "working_directory": "always_home"
// 4. Always use a specific directory. This value will be shell expanded.
// If this path is not a valid directory the terminal will default to
// this platform's home directory (if we can find it)
// "working_directory": {
// "always": {
// "directory": "~/zed/projects/"
// }
// }
//
// 1. Do not soft wrap.
// "soft_wrap": "none",
// 2. Soft wrap lines that overflow the editor:
// "soft_wrap": "editor_width",
// 3. Soft wrap lines at the preferred line length
// "soft_wrap": "preferred_line_length",
"soft_wrap": "none",
// The column at which to soft-wrap lines, for buffers where soft-wrap
// is enabled.
"preferred_line_length": 80,
// Whether to indent lines using tab characters, as opposed to multiple
// spaces.
"hard_tabs": false,
// How many columns a tab should occupy.
"tab_size": 4,
// Settings specific to the terminal
"terminal": {
// What shell to use when opening a terminal. May take 3 values:
// 1. Use the system's default terminal configuration (e.g. $TERM).
// "shell": "system"
// 2. A program:
// "shell": {
// "program": "sh"
// }
// 3. A program with arguments:
// "shell": {
// "with_arguments": {
// "program": "/bin/bash",
// "arguments": ["--login"]
// }
// }
"shell": "system",
// What working directory to use when launching the terminal.
// May take 4 values:
// 1. Use the current file's project directory. Will Fallback to the
// first project directory strategy if unsuccessful
// "working_directory": "current_project_directory"
// 2. Use the first project in this workspace's directory
// "working_directory": "first_project_directory"
// 3. Always use this platform's home directory (if we can find it)
// "working_directory": "always_home"
// 4. Always use a specific directory. This value will be shell expanded.
// If this path is not a valid directory the terminal will default to
// this platform's home directory (if we can find it)
// "working_directory": {
// "always": {
// "directory": "~/zed/projects/"
// }
// }
//
//
"working_directory": "current_project_directory",
// Set the cursor blinking behavior in the terminal.
// May take 4 values:
// 1. Never blink the cursor, ignoring the terminal mode
// "blinking": "off",
// 2. Default the cursor blink to off, but allow the terminal to
// set blinking
// "blinking": "terminal_controlled",
// 3. Always blink the cursor, ignoring the terminal mode
// "blinking": "on",
"blinking": "terminal_controlled",
// Set whether Alternate Scroll mode (code: ?1007) is active by default.
// Alternate Scroll mode converts mouse scroll events into up / down key
// presses when in the alternate screen (e.g. when running applications
// like vim or less). The terminal can still set and unset this mode.
// May take 2 values:
// 1. Default alternate scroll mode to on
// "alternate_scroll": "on",
// 2. Default alternate scroll mode to off
// "alternate_scroll": "off",
"alternate_scroll": "off",
// Set whether the option key behaves as the meta key.
// May take 2 values:
// 1. Rely on default platform handling of option key, on macOS
// this means generating certain unicode characters
// "option_to_meta": false,
// 2. Make the option keys behave as a 'meta' key, e.g. for emacs
// "option_to_meta": true,
"option_as_meta": false,
// Any key-value pairs added to this list will be added to the terminal's
// enviroment. Use `:` to seperate multiple values.
"env": {
// "KEY": "value1:value2"
}
// Set the terminal's font size. If this option is not included,
// the terminal will default to matching the buffer's font size.
// "font_size": "15"
// Set the terminal's font family. If this option is not included,
// the terminal will default to matching the buffer's font family.
// "font_family": "Zed Mono"
},
// Different settings for specific languages.
"languages": {
"Plain Text": {
"soft_wrap": "preferred_line_length"
},
"C": {
"tab_size": 2
},
"C++": {
"tab_size": 2
},
"Elixir": {
"tab_size": 2
},
"Go": {
"tab_size": 4,
"hard_tabs": true
},
"Markdown": {
"soft_wrap": "preferred_line_length"
},
"Rust": {
"tab_size": 4
},
"JavaScript": {
"tab_size": 2
},
"TypeScript": {
"tab_size": 2
},
"TSX": {
"tab_size": 2
}
},
// LSP Specific settings.
"lsp": {
// Specify the LSP name as a key here.
// As of 8/10/22, supported LSPs are:
// pyright
// gopls
// rust-analyzer
// typescript-language-server
// vscode-json-languageserver
// "rust_analyzer": {
// //These initialization options are merged into Zed's defaults
// "initialization_options": {
// "checkOnSave": {
// "command": "clippy"
// }
// }
// }
//
"working_directory": "current_project_directory",
// Set the cursor blinking behavior in the terminal.
// May take 4 values:
// 1. Never blink the cursor, ignoring the terminal mode
// "blinking": "off",
// 2. Default the cursor blink to off, but allow the terminal to
// set blinking
// "blinking": "terminal_controlled",
// 3. Always blink the cursor, ignoring the terminal mode
// "blinking": "on",
"blinking": "terminal_controlled",
// Set whether Alternate Scroll mode (code: ?1007) is active by default.
// Alternate Scroll mode converts mouse scroll events into up / down key
// presses when in the alternate screen (e.g. when running applications
// like vim or less). The terminal can still set and unset this mode.
// May take 2 values:
// 1. Default alternate scroll mode to on
// "alternate_scroll": "on",
// 2. Default alternate scroll mode to off
// "alternate_scroll": "off",
"alternate_scroll": "off",
// Set whether the option key behaves as the meta key.
// May take 2 values:
// 1. Rely on default platform handling of option key, on macOS
// this means generating certain unicode characters
// "option_to_meta": false,
// 2. Make the option keys behave as a 'meta' key, e.g. for emacs
// "option_to_meta": true,
"option_as_meta": false,
// Whether or not selecting text in the terminal will automatically
// copy to the system clipboard.
"copy_on_select": false,
// Any key-value pairs added to this list will be added to the terminal's
// enviroment. Use `:` to seperate multiple values.
"env": {
// "KEY": "value1:value2"
}
// Set the terminal's font size. If this option is not included,
// the terminal will default to matching the buffer's font size.
// "font_size": "15"
// Set the terminal's font family. If this option is not included,
// the terminal will default to matching the buffer's font family.
// "font_family": "Zed Mono"
},
// Different settings for specific languages.
"languages": {
"Plain Text": {
"soft_wrap": "preferred_line_length"
},
"C": {
"tab_size": 2
},
"C++": {
"tab_size": 2
},
"Elixir": {
"tab_size": 2
},
"Go": {
"tab_size": 4,
"hard_tabs": true
},
"Markdown": {
"soft_wrap": "preferred_line_length"
},
"Rust": {
"tab_size": 4
},
"JavaScript": {
"tab_size": 2
},
"TypeScript": {
"tab_size": 2
},
"TSX": {
"tab_size": 2
}
},
// LSP Specific settings.
"lsp": {
// Specify the LSP name as a key here.
// As of 8/10/22, supported LSPs are:
// pyright
// gopls
// rust-analyzer
// typescript-language-server
// vscode-json-languageserver
// "rust_analyzer": {
// //These initialization options are merged into Zed's defaults
// "initialization_options": {
// "checkOnSave": {
// "command": "clippy"
// }
// }
// }
}
}

View File

@@ -46,6 +46,7 @@ impl ActivityIndicator {
cx: &mut ViewContext<Workspace>,
) -> ViewHandle<ActivityIndicator> {
let project = workspace.project().clone();
let auto_updater = AutoUpdater::get(cx);
let this = cx.add_view(|cx: &mut ViewContext<Self>| {
let mut status_events = languages.language_server_binary_statuses();
cx.spawn_weak(|this, mut cx| async move {
@@ -66,11 +67,14 @@ impl ActivityIndicator {
})
.detach();
cx.observe(&project, |_, _, cx| cx.notify()).detach();
if let Some(auto_updater) = auto_updater.as_ref() {
cx.observe(auto_updater, |_, _, cx| cx.notify()).detach();
}
Self {
statuses: Default::default(),
project: project.clone(),
auto_updater: AutoUpdater::get(cx),
auto_updater,
}
});
cx.subscribe(&this, move |workspace, _, event, cx| match event {
@@ -285,7 +289,7 @@ impl View for ActivityIndicator {
.workspace
.status_bar
.lsp_status;
let style = if state.hovered && action.is_some() {
let style = if state.hovered() && action.is_some() {
theme.hover.as_ref().unwrap_or(&theme.default)
} else {
&theme.default

29
crates/assets/build.rs Normal file
View File

@@ -0,0 +1,29 @@
use std::process::Command;
fn main() {
let output = Command::new("npm")
.current_dir("../../styles")
.args(["install", "--no-save"])
.output()
.expect("failed to run npm");
if !output.status.success() {
panic!(
"failed to install theme dependencies {}",
String::from_utf8_lossy(&output.stderr)
);
}
let output = Command::new("npm")
.current_dir("../../styles")
.args(["run", "build"])
.output()
.expect("failed to run npm");
if !output.status.success() {
panic!(
"build script failed {}",
String::from_utf8_lossy(&output.stderr)
);
}
println!("cargo:rerun-if-changed=../../styles/src");
}

View File

@@ -1,13 +1,14 @@
mod update_notification;
use anyhow::{anyhow, Context, Result};
use client::{http::HttpClient, ZED_SECRET_CLIENT_TOKEN};
use client::{http::HttpClient, ZED_SECRET_CLIENT_TOKEN, ZED_SERVER_URL};
use gpui::{
actions, platform::AppVersion, AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle,
MutableAppContext, Task, WeakViewHandle,
};
use lazy_static::lazy_static;
use serde::Deserialize;
use settings::ReleaseChannel;
use smol::{fs::File, io::AsyncReadExt, process::Command};
use std::{env, ffi::OsString, path::PathBuf, sync::Arc, time::Duration};
use update_notification::UpdateNotification;
@@ -40,7 +41,7 @@ pub struct AutoUpdater {
current_version: AppVersion,
http_client: Arc<dyn HttpClient>,
pending_poll: Option<Task<()>>,
db: Arc<project::Db>,
db: project::Db,
server_url: String,
}
@@ -54,13 +55,9 @@ impl Entity for AutoUpdater {
type Event = ();
}
pub fn init(
db: Arc<project::Db>,
http_client: Arc<dyn HttpClient>,
server_url: String,
cx: &mut MutableAppContext,
) {
pub fn init(db: project::Db, http_client: Arc<dyn HttpClient>, cx: &mut MutableAppContext) {
if let Some(version) = (*ZED_APP_VERSION).or_else(|| cx.platform().app_version().ok()) {
let server_url = ZED_SERVER_URL.to_string();
let auto_updater = cx.add_model(|cx| {
let updater = AutoUpdater::new(version, db.clone(), http_client, server_url.clone());
updater.start_polling(cx).detach();
@@ -116,7 +113,7 @@ impl AutoUpdater {
fn new(
current_version: AppVersion,
db: Arc<project::Db>,
db: project::Db,
http_client: Arc<dyn HttpClient>,
server_url: String,
) -> Self {
@@ -177,9 +174,19 @@ impl AutoUpdater {
this.current_version,
)
});
let preview_param = cx.read(|cx| {
if cx.has_global::<ReleaseChannel>() {
if *cx.global::<ReleaseChannel>() == ReleaseChannel::Preview {
return "&preview=1";
}
}
""
});
let mut response = client
.get(
&format!("{server_url}/api/releases/latest?token={ZED_SECRET_CLIENT_TOKEN}&asset=Zed.dmg"),
&format!("{server_url}/api/releases/latest?token={ZED_SECRET_CLIENT_TOKEN}&asset=Zed.dmg{preview_param}"),
Default::default(),
true,
)
@@ -211,11 +218,14 @@ impl AutoUpdater {
let temp_dir = tempdir::TempDir::new("zed-auto-update")?;
let dmg_path = temp_dir.path().join("Zed.dmg");
let mount_path = temp_dir.path().join("Zed");
let mut mounted_app_path: OsString = mount_path.join("Zed.app").into();
mounted_app_path.push("/");
let running_app_path = ZED_APP_PATH
.clone()
.map_or_else(|| cx.platform().app_path(), Ok)?;
let running_app_filename = running_app_path
.file_name()
.ok_or_else(|| anyhow!("invalid running app path"))?;
let mut mounted_app_path: OsString = mount_path.join(running_app_filename).into();
mounted_app_path.push("/");
let mut dmg_file = File::create(&dmg_path).await?;
let mut response = client.get(&release.url, Default::default(), true).await?;
@@ -283,9 +293,9 @@ impl AutoUpdater {
let db = self.db.clone();
cx.background().spawn(async move {
if should_show {
db.write([(SHOULD_SHOW_UPDATE_NOTIFICATION_KEY, "")])?;
db.write_kvp(SHOULD_SHOW_UPDATE_NOTIFICATION_KEY, "")?;
} else {
db.delete([(SHOULD_SHOW_UPDATE_NOTIFICATION_KEY)])?;
db.delete_kvp(SHOULD_SHOW_UPDATE_NOTIFICATION_KEY)?;
}
Ok(())
})
@@ -293,8 +303,7 @@ impl AutoUpdater {
fn should_show_update_notification(&self, cx: &AppContext) -> Task<Result<bool>> {
let db = self.db.clone();
cx.background().spawn(async move {
Ok(db.read([(SHOULD_SHOW_UPDATE_NOTIFICATION_KEY)])?[0].is_some())
})
cx.background()
.spawn(async move { Ok(db.read_kvp(SHOULD_SHOW_UPDATE_NOTIFICATION_KEY)?.is_some()) })
}
}

View File

@@ -5,7 +5,7 @@ use gpui::{
Element, Entity, MouseButton, View, ViewContext,
};
use menu::Cancel;
use settings::Settings;
use settings::{ReleaseChannel, Settings};
use workspace::Notification;
pub struct UpdateNotification {
@@ -29,13 +29,15 @@ impl View for UpdateNotification {
let theme = cx.global::<Settings>().theme.clone();
let theme = &theme.update_notification;
let app_name = cx.global::<ReleaseChannel>().name();
MouseEventHandler::<ViewReleaseNotes>::new(0, cx, |state, cx| {
Flex::column()
.with_child(
Flex::row()
.with_child(
Text::new(
format!("Updated to Zed {}", self.version),
format!("Updated to {app_name} {}", self.version),
theme.message.text.clone(),
)
.contained()
@@ -49,7 +51,7 @@ impl View for UpdateNotification {
.with_child(
MouseEventHandler::<Cancel>::new(0, cx, |state, _| {
let style = theme.dismiss_button.style_for(state, false);
Svg::new("icons/x_mark_thin_8.svg")
Svg::new("icons/x_mark_8.svg")
.with_color(style.color)
.constrained()
.with_width(style.icon_width)

40
crates/call/Cargo.toml Normal file
View File

@@ -0,0 +1,40 @@
[package]
name = "call"
version = "0.1.0"
edition = "2021"
[lib]
path = "src/call.rs"
doctest = false
[features]
test-support = [
"client/test-support",
"collections/test-support",
"gpui/test-support",
"live_kit_client/test-support",
"project/test-support",
"util/test-support"
]
[dependencies]
client = { path = "../client" }
collections = { path = "../collections" }
gpui = { path = "../gpui" }
live_kit_client = { path = "../live_kit_client" }
media = { path = "../media" }
project = { path = "../project" }
util = { path = "../util" }
anyhow = "1.0.38"
async-broadcast = "0.4"
futures = "0.3"
postage = { version = "0.4.1", features = ["futures-traits"] }
[dev-dependencies]
client = { path = "../client", features = ["test-support"] }
collections = { path = "../collections", features = ["test-support"] }
gpui = { path = "../gpui", features = ["test-support"] }
live_kit_client = { path = "../live_kit_client", features = ["test-support"] }
project = { path = "../project", features = ["test-support"] }
util = { path = "../util", features = ["test-support"] }

300
crates/call/src/call.rs Normal file
View File

@@ -0,0 +1,300 @@
pub mod participant;
pub mod room;
use anyhow::{anyhow, Result};
use client::{proto, Client, TypedEnvelope, User, UserStore};
use collections::HashSet;
use gpui::{
AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle, MutableAppContext,
Subscription, Task, WeakModelHandle,
};
pub use participant::ParticipantLocation;
use postage::watch;
use project::Project;
pub use room::Room;
use std::sync::Arc;
pub fn init(client: Arc<Client>, user_store: ModelHandle<UserStore>, cx: &mut MutableAppContext) {
let active_call = cx.add_model(|cx| ActiveCall::new(client, user_store, cx));
cx.set_global(active_call);
}
#[derive(Clone)]
pub struct IncomingCall {
pub room_id: u64,
pub caller: Arc<User>,
pub participants: Vec<Arc<User>>,
pub initial_project: Option<proto::ParticipantProject>,
}
pub struct ActiveCall {
room: Option<(ModelHandle<Room>, Vec<Subscription>)>,
location: Option<WeakModelHandle<Project>>,
pending_invites: HashSet<u64>,
incoming_call: (
watch::Sender<Option<IncomingCall>>,
watch::Receiver<Option<IncomingCall>>,
),
client: Arc<Client>,
user_store: ModelHandle<UserStore>,
_subscriptions: Vec<client::Subscription>,
}
impl Entity for ActiveCall {
type Event = room::Event;
}
impl ActiveCall {
fn new(
client: Arc<Client>,
user_store: ModelHandle<UserStore>,
cx: &mut ModelContext<Self>,
) -> Self {
Self {
room: None,
location: None,
pending_invites: Default::default(),
incoming_call: watch::channel(),
_subscriptions: vec![
client.add_request_handler(cx.handle(), Self::handle_incoming_call),
client.add_message_handler(cx.handle(), Self::handle_call_canceled),
],
client,
user_store,
}
}
async fn handle_incoming_call(
this: ModelHandle<Self>,
envelope: TypedEnvelope<proto::IncomingCall>,
_: Arc<Client>,
mut cx: AsyncAppContext,
) -> Result<proto::Ack> {
let user_store = this.read_with(&cx, |this, _| this.user_store.clone());
let call = IncomingCall {
room_id: envelope.payload.room_id,
participants: user_store
.update(&mut cx, |user_store, cx| {
user_store.get_users(envelope.payload.participant_user_ids, cx)
})
.await?,
caller: user_store
.update(&mut cx, |user_store, cx| {
user_store.get_user(envelope.payload.caller_user_id, cx)
})
.await?,
initial_project: envelope.payload.initial_project,
};
this.update(&mut cx, |this, _| {
*this.incoming_call.0.borrow_mut() = Some(call);
});
Ok(proto::Ack {})
}
async fn handle_call_canceled(
this: ModelHandle<Self>,
_: TypedEnvelope<proto::CallCanceled>,
_: Arc<Client>,
mut cx: AsyncAppContext,
) -> Result<()> {
this.update(&mut cx, |this, _| {
*this.incoming_call.0.borrow_mut() = None;
});
Ok(())
}
pub fn global(cx: &AppContext) -> ModelHandle<Self> {
cx.global::<ModelHandle<Self>>().clone()
}
pub fn invite(
&mut self,
recipient_user_id: u64,
initial_project: Option<ModelHandle<Project>>,
cx: &mut ModelContext<Self>,
) -> Task<Result<()>> {
let client = self.client.clone();
let user_store = self.user_store.clone();
if !self.pending_invites.insert(recipient_user_id) {
return Task::ready(Err(anyhow!("user was already invited")));
}
cx.notify();
cx.spawn(|this, mut cx| async move {
let invite = async {
if let Some(room) = this.read_with(&cx, |this, _| this.room().cloned()) {
let initial_project_id = if let Some(initial_project) = initial_project {
Some(
room.update(&mut cx, |room, cx| {
room.share_project(initial_project, cx)
})
.await?,
)
} else {
None
};
room.update(&mut cx, |room, cx| {
room.call(recipient_user_id, initial_project_id, cx)
})
.await?;
} else {
let room = cx
.update(|cx| {
Room::create(recipient_user_id, initial_project, client, user_store, cx)
})
.await?;
this.update(&mut cx, |this, cx| this.set_room(Some(room), cx))
.await?;
};
Ok(())
};
let result = invite.await;
this.update(&mut cx, |this, cx| {
this.pending_invites.remove(&recipient_user_id);
cx.notify();
});
result
})
}
pub fn cancel_invite(
&mut self,
recipient_user_id: u64,
cx: &mut ModelContext<Self>,
) -> Task<Result<()>> {
let room_id = if let Some(room) = self.room() {
room.read(cx).id()
} else {
return Task::ready(Err(anyhow!("no active call")));
};
let client = self.client.clone();
cx.foreground().spawn(async move {
client
.request(proto::CancelCall {
room_id,
recipient_user_id,
})
.await?;
anyhow::Ok(())
})
}
pub fn incoming(&self) -> watch::Receiver<Option<IncomingCall>> {
self.incoming_call.1.clone()
}
pub fn accept_incoming(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
if self.room.is_some() {
return Task::ready(Err(anyhow!("cannot join while on another call")));
}
let call = if let Some(call) = self.incoming_call.1.borrow().clone() {
call
} else {
return Task::ready(Err(anyhow!("no incoming call")));
};
let join = Room::join(&call, self.client.clone(), self.user_store.clone(), cx);
cx.spawn(|this, mut cx| async move {
let room = join.await?;
this.update(&mut cx, |this, cx| this.set_room(Some(room.clone()), cx))
.await?;
Ok(())
})
}
pub fn decline_incoming(&mut self) -> Result<()> {
let call = self
.incoming_call
.0
.borrow_mut()
.take()
.ok_or_else(|| anyhow!("no incoming call"))?;
self.client.send(proto::DeclineCall {
room_id: call.room_id,
})?;
Ok(())
}
pub fn hang_up(&mut self, cx: &mut ModelContext<Self>) -> Result<()> {
if let Some((room, _)) = self.room.take() {
room.update(cx, |room, cx| room.leave(cx))?;
cx.notify();
}
Ok(())
}
pub fn share_project(
&mut self,
project: ModelHandle<Project>,
cx: &mut ModelContext<Self>,
) -> Task<Result<u64>> {
if let Some((room, _)) = self.room.as_ref() {
room.update(cx, |room, cx| room.share_project(project, cx))
} else {
Task::ready(Err(anyhow!("no active call")))
}
}
pub fn set_location(
&mut self,
project: Option<&ModelHandle<Project>>,
cx: &mut ModelContext<Self>,
) -> Task<Result<()>> {
self.location = project.map(|project| project.downgrade());
if let Some((room, _)) = self.room.as_ref() {
room.update(cx, |room, cx| room.set_location(project, cx))
} else {
Task::ready(Ok(()))
}
}
fn set_room(
&mut self,
room: Option<ModelHandle<Room>>,
cx: &mut ModelContext<Self>,
) -> Task<Result<()>> {
if room.as_ref() != self.room.as_ref().map(|room| &room.0) {
cx.notify();
if let Some(room) = room {
if room.read(cx).status().is_offline() {
self.room = None;
Task::ready(Ok(()))
} else {
let subscriptions = vec![
cx.observe(&room, |this, room, cx| {
if room.read(cx).status().is_offline() {
this.set_room(None, cx).detach_and_log_err(cx);
}
cx.notify();
}),
cx.subscribe(&room, |_, _, event, cx| cx.emit(event.clone())),
];
self.room = Some((room.clone(), subscriptions));
let location = self.location.and_then(|location| location.upgrade(cx));
room.update(cx, |room, cx| room.set_location(location.as_ref(), cx))
}
} else {
self.room = None;
Task::ready(Ok(()))
}
} else {
Task::ready(Ok(()))
}
}
pub fn room(&self) -> Option<&ModelHandle<Room>> {
self.room.as_ref().map(|(room, _)| room)
}
pub fn pending_invites(&self) -> &HashSet<u64> {
&self.pending_invites
}
}

View File

@@ -0,0 +1,56 @@
use anyhow::{anyhow, Result};
use client::{proto, User};
use collections::HashMap;
use gpui::WeakModelHandle;
pub use live_kit_client::Frame;
use project::Project;
use std::sync::Arc;
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum ParticipantLocation {
SharedProject { project_id: u64 },
UnsharedProject,
External,
}
impl ParticipantLocation {
pub fn from_proto(location: Option<proto::ParticipantLocation>) -> Result<Self> {
match location.and_then(|l| l.variant) {
Some(proto::participant_location::Variant::SharedProject(project)) => {
Ok(Self::SharedProject {
project_id: project.id,
})
}
Some(proto::participant_location::Variant::UnsharedProject(_)) => {
Ok(Self::UnsharedProject)
}
Some(proto::participant_location::Variant::External(_)) => Ok(Self::External),
None => Err(anyhow!("participant location was not provided")),
}
}
}
#[derive(Clone, Default)]
pub struct LocalParticipant {
pub projects: Vec<proto::ParticipantProject>,
pub active_project: Option<WeakModelHandle<Project>>,
}
#[derive(Clone)]
pub struct RemoteParticipant {
pub user: Arc<User>,
pub projects: Vec<proto::ParticipantProject>,
pub location: ParticipantLocation,
pub tracks: HashMap<live_kit_client::Sid, Arc<RemoteVideoTrack>>,
}
#[derive(Clone)]
pub struct RemoteVideoTrack {
pub(crate) live_kit_track: Arc<live_kit_client::RemoteVideoTrack>,
}
impl RemoteVideoTrack {
pub fn frames(&self) -> async_broadcast::Receiver<Frame> {
self.live_kit_track.frames()
}
}

760
crates/call/src/room.rs Normal file
View File

@@ -0,0 +1,760 @@
use crate::{
participant::{LocalParticipant, ParticipantLocation, RemoteParticipant, RemoteVideoTrack},
IncomingCall,
};
use anyhow::{anyhow, Result};
use client::{proto, Client, PeerId, TypedEnvelope, User, UserStore};
use collections::{BTreeMap, HashSet};
use futures::StreamExt;
use gpui::{AsyncAppContext, Entity, ModelContext, ModelHandle, MutableAppContext, Task};
use live_kit_client::{LocalTrackPublication, LocalVideoTrack, RemoteVideoTrackUpdate};
use postage::stream::Stream;
use project::Project;
use std::{mem, os::unix::prelude::OsStrExt, sync::Arc};
use util::{post_inc, ResultExt};
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Event {
ParticipantLocationChanged {
participant_id: PeerId,
},
RemoteVideoTracksChanged {
participant_id: PeerId,
},
RemoteProjectShared {
owner: Arc<User>,
project_id: u64,
worktree_root_names: Vec<String>,
},
RemoteProjectUnshared {
project_id: u64,
},
Left,
}
pub struct Room {
id: u64,
live_kit: Option<LiveKitRoom>,
status: RoomStatus,
local_participant: LocalParticipant,
remote_participants: BTreeMap<PeerId, RemoteParticipant>,
pending_participants: Vec<Arc<User>>,
participant_user_ids: HashSet<u64>,
pending_call_count: usize,
leave_when_empty: bool,
client: Arc<Client>,
user_store: ModelHandle<UserStore>,
subscriptions: Vec<client::Subscription>,
pending_room_update: Option<Task<()>>,
}
impl Entity for Room {
type Event = Event;
fn release(&mut self, _: &mut MutableAppContext) {
if self.status.is_online() {
self.client.send(proto::LeaveRoom { id: self.id }).log_err();
}
}
}
impl Room {
fn new(
id: u64,
live_kit_connection_info: Option<proto::LiveKitConnectionInfo>,
client: Arc<Client>,
user_store: ModelHandle<UserStore>,
cx: &mut ModelContext<Self>,
) -> Self {
let mut client_status = client.status();
cx.spawn_weak(|this, mut cx| async move {
let is_connected = client_status
.next()
.await
.map_or(false, |s| s.is_connected());
// Even if we're initially connected, any future change of the status means we momentarily disconnected.
if !is_connected || client_status.next().await.is_some() {
if let Some(this) = this.upgrade(&cx) {
let _ = this.update(&mut cx, |this, cx| this.leave(cx));
}
}
})
.detach();
let live_kit_room = if let Some(connection_info) = live_kit_connection_info {
let room = live_kit_client::Room::new();
let mut status = room.status();
// Consume the initial status of the room.
let _ = status.try_recv();
let _maintain_room = cx.spawn_weak(|this, mut cx| async move {
while let Some(status) = status.next().await {
let this = if let Some(this) = this.upgrade(&cx) {
this
} else {
break;
};
if status == live_kit_client::ConnectionState::Disconnected {
this.update(&mut cx, |this, cx| this.leave(cx).log_err());
break;
}
}
});
let mut track_changes = room.remote_video_track_updates();
let _maintain_tracks = cx.spawn_weak(|this, mut cx| async move {
while let Some(track_change) = track_changes.next().await {
let this = if let Some(this) = this.upgrade(&cx) {
this
} else {
break;
};
this.update(&mut cx, |this, cx| {
this.remote_video_track_updated(track_change, cx).log_err()
});
}
});
cx.foreground()
.spawn(room.connect(&connection_info.server_url, &connection_info.token))
.detach_and_log_err(cx);
Some(LiveKitRoom {
room,
screen_track: ScreenTrack::None,
next_publish_id: 0,
_maintain_room,
_maintain_tracks,
})
} else {
None
};
Self {
id,
live_kit: live_kit_room,
status: RoomStatus::Online,
participant_user_ids: Default::default(),
local_participant: Default::default(),
remote_participants: Default::default(),
pending_participants: Default::default(),
pending_call_count: 0,
subscriptions: vec![client.add_message_handler(cx.handle(), Self::handle_room_updated)],
leave_when_empty: false,
pending_room_update: None,
client,
user_store,
}
}
pub(crate) fn create(
recipient_user_id: u64,
initial_project: Option<ModelHandle<Project>>,
client: Arc<Client>,
user_store: ModelHandle<UserStore>,
cx: &mut MutableAppContext,
) -> Task<Result<ModelHandle<Self>>> {
cx.spawn(|mut cx| async move {
let response = client.request(proto::CreateRoom {}).await?;
let room_proto = response.room.ok_or_else(|| anyhow!("invalid room"))?;
let room = cx.add_model(|cx| {
Self::new(
room_proto.id,
response.live_kit_connection_info,
client,
user_store,
cx,
)
});
let initial_project_id = if let Some(initial_project) = initial_project {
let initial_project_id = room
.update(&mut cx, |room, cx| {
room.share_project(initial_project.clone(), cx)
})
.await?;
Some(initial_project_id)
} else {
None
};
match room
.update(&mut cx, |room, cx| {
room.leave_when_empty = true;
room.call(recipient_user_id, initial_project_id, cx)
})
.await
{
Ok(()) => Ok(room),
Err(error) => Err(anyhow!("room creation failed: {:?}", error)),
}
})
}
pub(crate) fn join(
call: &IncomingCall,
client: Arc<Client>,
user_store: ModelHandle<UserStore>,
cx: &mut MutableAppContext,
) -> Task<Result<ModelHandle<Self>>> {
let room_id = call.room_id;
cx.spawn(|mut cx| async move {
let response = client.request(proto::JoinRoom { id: room_id }).await?;
let room_proto = response.room.ok_or_else(|| anyhow!("invalid room"))?;
let room = cx.add_model(|cx| {
Self::new(
room_id,
response.live_kit_connection_info,
client,
user_store,
cx,
)
});
room.update(&mut cx, |room, cx| {
room.leave_when_empty = true;
room.apply_room_update(room_proto, cx)?;
anyhow::Ok(())
})?;
Ok(room)
})
}
fn should_leave(&self) -> bool {
self.leave_when_empty
&& self.pending_room_update.is_none()
&& self.pending_participants.is_empty()
&& self.remote_participants.is_empty()
&& self.pending_call_count == 0
}
pub(crate) fn leave(&mut self, cx: &mut ModelContext<Self>) -> Result<()> {
if self.status.is_offline() {
return Err(anyhow!("room is offline"));
}
cx.notify();
cx.emit(Event::Left);
self.status = RoomStatus::Offline;
self.remote_participants.clear();
self.pending_participants.clear();
self.participant_user_ids.clear();
self.subscriptions.clear();
self.live_kit.take();
self.client.send(proto::LeaveRoom { id: self.id })?;
Ok(())
}
pub fn id(&self) -> u64 {
self.id
}
pub fn status(&self) -> RoomStatus {
self.status
}
pub fn local_participant(&self) -> &LocalParticipant {
&self.local_participant
}
pub fn remote_participants(&self) -> &BTreeMap<PeerId, RemoteParticipant> {
&self.remote_participants
}
pub fn pending_participants(&self) -> &[Arc<User>] {
&self.pending_participants
}
pub fn contains_participant(&self, user_id: u64) -> bool {
self.participant_user_ids.contains(&user_id)
}
async fn handle_room_updated(
this: ModelHandle<Self>,
envelope: TypedEnvelope<proto::RoomUpdated>,
_: Arc<Client>,
mut cx: AsyncAppContext,
) -> Result<()> {
let room = envelope
.payload
.room
.ok_or_else(|| anyhow!("invalid room"))?;
this.update(&mut cx, |this, cx| this.apply_room_update(room, cx))
}
fn apply_room_update(
&mut self,
mut room: proto::Room,
cx: &mut ModelContext<Self>,
) -> Result<()> {
// Filter ourselves out from the room's participants.
let local_participant_ix = room
.participants
.iter()
.position(|participant| Some(participant.user_id) == self.client.user_id());
let local_participant = local_participant_ix.map(|ix| room.participants.swap_remove(ix));
let remote_participant_user_ids = room
.participants
.iter()
.map(|p| p.user_id)
.collect::<Vec<_>>();
let (remote_participants, pending_participants) =
self.user_store.update(cx, move |user_store, cx| {
(
user_store.get_users(remote_participant_user_ids, cx),
user_store.get_users(room.pending_participant_user_ids, cx),
)
});
self.pending_room_update = Some(cx.spawn(|this, mut cx| async move {
let (remote_participants, pending_participants) =
futures::join!(remote_participants, pending_participants);
this.update(&mut cx, |this, cx| {
this.participant_user_ids.clear();
if let Some(participant) = local_participant {
this.local_participant.projects = participant.projects;
} else {
this.local_participant.projects.clear();
}
if let Some(participants) = remote_participants.log_err() {
for (participant, user) in room.participants.into_iter().zip(participants) {
let peer_id = PeerId(participant.peer_id);
this.participant_user_ids.insert(participant.user_id);
let old_projects = this
.remote_participants
.get(&peer_id)
.into_iter()
.flat_map(|existing| &existing.projects)
.map(|project| project.id)
.collect::<HashSet<_>>();
let new_projects = participant
.projects
.iter()
.map(|project| project.id)
.collect::<HashSet<_>>();
for project in &participant.projects {
if !old_projects.contains(&project.id) {
cx.emit(Event::RemoteProjectShared {
owner: user.clone(),
project_id: project.id,
worktree_root_names: project.worktree_root_names.clone(),
});
}
}
for unshared_project_id in old_projects.difference(&new_projects) {
cx.emit(Event::RemoteProjectUnshared {
project_id: *unshared_project_id,
});
}
let location = ParticipantLocation::from_proto(participant.location)
.unwrap_or(ParticipantLocation::External);
if let Some(remote_participant) = this.remote_participants.get_mut(&peer_id)
{
remote_participant.projects = participant.projects;
if location != remote_participant.location {
remote_participant.location = location;
cx.emit(Event::ParticipantLocationChanged {
participant_id: peer_id,
});
}
} else {
this.remote_participants.insert(
peer_id,
RemoteParticipant {
user: user.clone(),
projects: participant.projects,
location,
tracks: Default::default(),
},
);
if let Some(live_kit) = this.live_kit.as_ref() {
let tracks =
live_kit.room.remote_video_tracks(&peer_id.0.to_string());
for track in tracks {
this.remote_video_track_updated(
RemoteVideoTrackUpdate::Subscribed(track),
cx,
)
.log_err();
}
}
}
}
this.remote_participants.retain(|_, participant| {
if this.participant_user_ids.contains(&participant.user.id) {
true
} else {
for project in &participant.projects {
cx.emit(Event::RemoteProjectUnshared {
project_id: project.id,
});
}
false
}
});
}
if let Some(pending_participants) = pending_participants.log_err() {
this.pending_participants = pending_participants;
for participant in &this.pending_participants {
this.participant_user_ids.insert(participant.id);
}
}
this.pending_room_update.take();
if this.should_leave() {
let _ = this.leave(cx);
}
this.check_invariants();
cx.notify();
});
}));
cx.notify();
Ok(())
}
fn remote_video_track_updated(
&mut self,
change: RemoteVideoTrackUpdate,
cx: &mut ModelContext<Self>,
) -> Result<()> {
match change {
RemoteVideoTrackUpdate::Subscribed(track) => {
let peer_id = PeerId(track.publisher_id().parse()?);
let track_id = track.sid().to_string();
let participant = self
.remote_participants
.get_mut(&peer_id)
.ok_or_else(|| anyhow!("subscribed to track by unknown participant"))?;
participant.tracks.insert(
track_id.clone(),
Arc::new(RemoteVideoTrack {
live_kit_track: track,
}),
);
cx.emit(Event::RemoteVideoTracksChanged {
participant_id: peer_id,
});
}
RemoteVideoTrackUpdate::Unsubscribed {
publisher_id,
track_id,
} => {
let peer_id = PeerId(publisher_id.parse()?);
let participant = self
.remote_participants
.get_mut(&peer_id)
.ok_or_else(|| anyhow!("unsubscribed from track by unknown participant"))?;
participant.tracks.remove(&track_id);
cx.emit(Event::RemoteVideoTracksChanged {
participant_id: peer_id,
});
}
}
cx.notify();
Ok(())
}
fn check_invariants(&self) {
#[cfg(any(test, feature = "test-support"))]
{
for participant in self.remote_participants.values() {
assert!(self.participant_user_ids.contains(&participant.user.id));
}
for participant in &self.pending_participants {
assert!(self.participant_user_ids.contains(&participant.id));
}
assert_eq!(
self.participant_user_ids.len(),
self.remote_participants.len() + self.pending_participants.len()
);
}
}
pub(crate) fn call(
&mut self,
recipient_user_id: u64,
initial_project_id: Option<u64>,
cx: &mut ModelContext<Self>,
) -> Task<Result<()>> {
if self.status.is_offline() {
return Task::ready(Err(anyhow!("room is offline")));
}
cx.notify();
let client = self.client.clone();
let room_id = self.id;
self.pending_call_count += 1;
cx.spawn(|this, mut cx| async move {
let result = client
.request(proto::Call {
room_id,
recipient_user_id,
initial_project_id,
})
.await;
this.update(&mut cx, |this, cx| {
this.pending_call_count -= 1;
if this.should_leave() {
this.leave(cx)?;
}
result
})?;
Ok(())
})
}
pub(crate) fn share_project(
&mut self,
project: ModelHandle<Project>,
cx: &mut ModelContext<Self>,
) -> Task<Result<u64>> {
if let Some(project_id) = project.read(cx).remote_id() {
return Task::ready(Ok(project_id));
}
let request = self.client.request(proto::ShareProject {
room_id: self.id(),
worktrees: project
.read(cx)
.worktrees(cx)
.map(|worktree| {
let worktree = worktree.read(cx);
proto::WorktreeMetadata {
id: worktree.id().to_proto(),
root_name: worktree.root_name().into(),
visible: worktree.is_visible(),
abs_path: worktree.abs_path().as_os_str().as_bytes().to_vec(),
}
})
.collect(),
});
cx.spawn(|this, mut cx| async move {
let response = request.await?;
project.update(&mut cx, |project, cx| {
project
.shared(response.project_id, cx)
.detach_and_log_err(cx)
});
// If the user's location is in this project, it changes from UnsharedProject to SharedProject.
this.update(&mut cx, |this, cx| {
let active_project = this.local_participant.active_project.as_ref();
if active_project.map_or(false, |location| *location == project) {
this.set_location(Some(&project), cx)
} else {
Task::ready(Ok(()))
}
})
.await?;
Ok(response.project_id)
})
}
pub(crate) fn set_location(
&mut self,
project: Option<&ModelHandle<Project>>,
cx: &mut ModelContext<Self>,
) -> Task<Result<()>> {
if self.status.is_offline() {
return Task::ready(Err(anyhow!("room is offline")));
}
let client = self.client.clone();
let room_id = self.id;
let location = if let Some(project) = project {
self.local_participant.active_project = Some(project.downgrade());
if let Some(project_id) = project.read(cx).remote_id() {
proto::participant_location::Variant::SharedProject(
proto::participant_location::SharedProject { id: project_id },
)
} else {
proto::participant_location::Variant::UnsharedProject(
proto::participant_location::UnsharedProject {},
)
}
} else {
self.local_participant.active_project = None;
proto::participant_location::Variant::External(proto::participant_location::External {})
};
cx.notify();
cx.foreground().spawn(async move {
client
.request(proto::UpdateParticipantLocation {
room_id,
location: Some(proto::ParticipantLocation {
variant: Some(location),
}),
})
.await?;
Ok(())
})
}
pub fn is_screen_sharing(&self) -> bool {
self.live_kit.as_ref().map_or(false, |live_kit| {
!matches!(live_kit.screen_track, ScreenTrack::None)
})
}
pub fn share_screen(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
if self.status.is_offline() {
return Task::ready(Err(anyhow!("room is offline")));
} else if self.is_screen_sharing() {
return Task::ready(Err(anyhow!("screen was already shared")));
}
let (displays, publish_id) = if let Some(live_kit) = self.live_kit.as_mut() {
let publish_id = post_inc(&mut live_kit.next_publish_id);
live_kit.screen_track = ScreenTrack::Pending { publish_id };
cx.notify();
(live_kit.room.display_sources(), publish_id)
} else {
return Task::ready(Err(anyhow!("live-kit was not initialized")));
};
cx.spawn_weak(|this, mut cx| async move {
let publish_track = async {
let displays = displays.await?;
let display = displays
.first()
.ok_or_else(|| anyhow!("no display found"))?;
let track = LocalVideoTrack::screen_share_for_display(&display);
this.upgrade(&cx)
.ok_or_else(|| anyhow!("room was dropped"))?
.read_with(&cx, |this, _| {
this.live_kit
.as_ref()
.map(|live_kit| live_kit.room.publish_video_track(&track))
})
.ok_or_else(|| anyhow!("live-kit was not initialized"))?
.await
};
let publication = publish_track.await;
this.upgrade(&cx)
.ok_or_else(|| anyhow!("room was dropped"))?
.update(&mut cx, |this, cx| {
let live_kit = this
.live_kit
.as_mut()
.ok_or_else(|| anyhow!("live-kit was not initialized"))?;
let canceled = if let ScreenTrack::Pending {
publish_id: cur_publish_id,
} = &live_kit.screen_track
{
*cur_publish_id != publish_id
} else {
true
};
match publication {
Ok(publication) => {
if canceled {
live_kit.room.unpublish_track(publication);
} else {
live_kit.screen_track = ScreenTrack::Published(publication);
cx.notify();
}
Ok(())
}
Err(error) => {
if canceled {
Ok(())
} else {
live_kit.screen_track = ScreenTrack::None;
cx.notify();
Err(error)
}
}
}
})
})
}
pub fn unshare_screen(&mut self, cx: &mut ModelContext<Self>) -> Result<()> {
if self.status.is_offline() {
return Err(anyhow!("room is offline"));
}
let live_kit = self
.live_kit
.as_mut()
.ok_or_else(|| anyhow!("live-kit was not initialized"))?;
match mem::take(&mut live_kit.screen_track) {
ScreenTrack::None => Err(anyhow!("screen was not shared")),
ScreenTrack::Pending { .. } => {
cx.notify();
Ok(())
}
ScreenTrack::Published(track) => {
live_kit.room.unpublish_track(track);
cx.notify();
Ok(())
}
}
}
#[cfg(any(test, feature = "test-support"))]
pub fn set_display_sources(&self, sources: Vec<live_kit_client::MacOSDisplay>) {
self.live_kit
.as_ref()
.unwrap()
.room
.set_display_sources(sources);
}
}
struct LiveKitRoom {
room: Arc<live_kit_client::Room>,
screen_track: ScreenTrack,
next_publish_id: usize,
_maintain_room: Task<()>,
_maintain_tracks: Task<()>,
}
enum ScreenTrack {
None,
Pending { publish_id: usize },
Published(LocalTrackPublication),
}
impl Default for ScreenTrack {
fn default() -> Self {
Self::None
}
}
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum RoomStatus {
Online,
Offline,
}
impl RoomStatus {
pub fn is_offline(&self) -> bool {
matches!(self, RoomStatus::Offline)
}
pub fn is_online(&self) -> bool {
matches!(self, RoomStatus::Online)
}
}

View File

@@ -1,32 +0,0 @@
[package]
name = "capture"
version = "0.1.0"
edition = "2021"
description = "An example of screen capture"
[dependencies]
gpui = { path = "../gpui" }
live_kit = { path = "../live_kit" }
media = { path = "../media" }
anyhow = "1.0.38"
block = "0.1"
bytes = "1.2"
byteorder = "1.4"
cocoa = "0.24"
core-foundation = "0.9.3"
core-graphics = "0.22.3"
foreign-types = "0.3"
futures = "0.3"
hmac = "0.12"
jwt = "0.16"
log = { version = "0.4.16", features = ["kv_unstable_serde"] }
objc = "0.2"
parking_lot = "0.11.1"
postage = { version = "0.4.1", features = ["futures-traits"] }
serde = { version = "1.0", features = ["derive", "rc"] }
sha2 = "0.10"
simplelog = "0.9"
[build-dependencies]
bindgen = "0.59.2"

View File

@@ -1,7 +0,0 @@
fn main() {
// Find WebRTC.framework as a sibling of the executable when running outside of an application bundle
println!("cargo:rustc-link-arg=-Wl,-rpath,@executable_path");
// Register exported Objective-C selectors, protocols, etc
println!("cargo:rustc-link-arg=-Wl,-ObjC");
}

View File

@@ -1,71 +0,0 @@
use anyhow::Result;
use hmac::{Hmac, Mac};
use jwt::SignWithKey;
use serde::Serialize;
use sha2::Sha256;
use std::{
ops::Add,
time::{Duration, SystemTime, UNIX_EPOCH},
};
static DEFAULT_TTL: Duration = Duration::from_secs(6 * 60 * 60); // 6 hours
#[derive(Default, Serialize)]
#[serde(rename_all = "camelCase")]
struct ClaimGrants<'a> {
iss: &'a str,
sub: &'a str,
iat: u64,
exp: u64,
nbf: u64,
jwtid: &'a str,
video: VideoGrant<'a>,
}
#[derive(Default, Serialize)]
#[serde(rename_all = "camelCase")]
struct VideoGrant<'a> {
room_create: Option<bool>,
room_join: Option<bool>,
room_list: Option<bool>,
room_record: Option<bool>,
room_admin: Option<bool>,
room: Option<&'a str>,
can_publish: Option<bool>,
can_subscribe: Option<bool>,
can_publish_data: Option<bool>,
hidden: Option<bool>,
recorder: Option<bool>,
}
pub fn create_token(
api_key: &str,
secret_key: &str,
room_name: &str,
participant_name: &str,
) -> Result<String> {
let secret_key: Hmac<Sha256> = Hmac::new_from_slice(secret_key.as_bytes())?;
let now = SystemTime::now();
let claims = ClaimGrants {
iss: api_key,
sub: participant_name,
iat: now.duration_since(UNIX_EPOCH).unwrap().as_secs(),
exp: now
.add(DEFAULT_TTL)
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs(),
nbf: 0,
jwtid: participant_name,
video: VideoGrant {
room: Some(room_name),
room_join: Some(true),
can_publish: Some(true),
can_subscribe: Some(true),
..Default::default()
},
};
Ok(claims.sign_with_key(&secret_key)?)
}

View File

@@ -1,143 +0,0 @@
mod live_kit_token;
use futures::StreamExt;
use gpui::{
actions,
elements::{Canvas, *},
keymap::Binding,
platform::current::Surface,
Menu, MenuItem, ViewContext,
};
use live_kit::{LocalVideoTrack, Room};
use log::LevelFilter;
use media::core_video::CVImageBuffer;
use postage::watch;
use simplelog::SimpleLogger;
use std::sync::Arc;
actions!(capture, [Quit]);
fn main() {
SimpleLogger::init(LevelFilter::Info, Default::default()).expect("could not initialize logger");
gpui::App::new(()).unwrap().run(|cx| {
cx.platform().activate(true);
cx.add_global_action(quit);
cx.add_bindings([Binding::new("cmd-q", Quit, None)]);
cx.set_menus(vec![Menu {
name: "Zed",
items: vec![MenuItem::Action {
name: "Quit",
action: Box::new(Quit),
}],
}]);
let live_kit_url = std::env::var("LIVE_KIT_URL").unwrap();
let live_kit_key = std::env::var("LIVE_KIT_KEY").unwrap();
let live_kit_secret = std::env::var("LIVE_KIT_SECRET").unwrap();
cx.spawn(|mut cx| async move {
let user1_token = live_kit_token::create_token(
&live_kit_key,
&live_kit_secret,
"test-room",
"test-participant-1",
)
.unwrap();
let room1 = Room::new();
room1.connect(&live_kit_url, &user1_token).await.unwrap();
let user2_token = live_kit_token::create_token(
&live_kit_key,
&live_kit_secret,
"test-room",
"test-participant-2",
)
.unwrap();
let room2 = Room::new();
room2.connect(&live_kit_url, &user2_token).await.unwrap();
cx.add_window(Default::default(), |cx| ScreenCaptureView::new(room2, cx));
let windows = live_kit::list_windows();
let window = windows
.iter()
.find(|w| w.owner_name.as_deref() == Some("Safari"))
.unwrap();
let track = LocalVideoTrack::screen_share_for_window(window.id);
room1.publish_video_track(&track).await.unwrap();
})
.detach();
});
}
struct ScreenCaptureView {
image_buffer: Option<CVImageBuffer>,
_room: Arc<Room>,
}
impl gpui::Entity for ScreenCaptureView {
type Event = ();
}
impl ScreenCaptureView {
pub fn new(room: Arc<Room>, cx: &mut ViewContext<Self>) -> Self {
let mut remote_video_tracks = room.remote_video_tracks();
cx.spawn_weak(|this, mut cx| async move {
if let Some(video_track) = remote_video_tracks.next().await {
let (mut frames_tx, mut frames_rx) = watch::channel_with(None);
video_track.add_renderer(move |frame| *frames_tx.borrow_mut() = Some(frame));
while let Some(frame) = frames_rx.next().await {
if let Some(this) = this.upgrade(&cx) {
this.update(&mut cx, |this, cx| {
this.image_buffer = frame;
cx.notify();
});
} else {
break;
}
}
}
})
.detach();
Self {
image_buffer: None,
_room: room,
}
}
}
impl gpui::View for ScreenCaptureView {
fn ui_name() -> &'static str {
"View"
}
fn render(&mut self, _: &mut gpui::RenderContext<Self>) -> gpui::ElementBox {
let image_buffer = self.image_buffer.clone();
let canvas = Canvas::new(move |bounds, _, cx| {
if let Some(image_buffer) = image_buffer.clone() {
cx.scene.push_surface(Surface {
bounds,
image_buffer,
});
}
});
if let Some(image_buffer) = self.image_buffer.as_ref() {
canvas
.constrained()
.with_width(image_buffer.width() as f32)
.with_height(image_buffer.height() as f32)
.aligned()
.boxed()
} else {
canvas.boxed()
}
}
}
fn quit(_: &Quit, cx: &mut gpui::MutableAppContext) {
cx.platform().quit();
}

View File

@@ -1,20 +0,0 @@
[package]
name = "chat_panel"
version = "0.1.0"
edition = "2021"
[lib]
path = "src/chat_panel.rs"
doctest = false
[dependencies]
client = { path = "../client" }
editor = { path = "../editor" }
gpui = { path = "../gpui" }
menu = { path = "../menu" }
settings = { path = "../settings" }
theme = { path = "../theme" }
util = { path = "../util" }
workspace = { path = "../workspace" }
postage = { version = "0.4.1", features = ["futures-traits"] }
time = { version = "0.3", features = ["serde", "serde-well-known"] }

View File

@@ -1,433 +0,0 @@
use client::{
channel::{Channel, ChannelEvent, ChannelList, ChannelMessage},
Client,
};
use editor::Editor;
use gpui::{
actions,
elements::*,
platform::CursorStyle,
views::{ItemType, Select, SelectStyle},
AnyViewHandle, AppContext, Entity, ModelHandle, MouseButton, MutableAppContext, RenderContext,
Subscription, Task, View, ViewContext, ViewHandle,
};
use menu::Confirm;
use postage::prelude::Stream;
use settings::{Settings, SoftWrap};
use std::sync::Arc;
use time::{OffsetDateTime, UtcOffset};
use util::{ResultExt, TryFutureExt};
const MESSAGE_LOADING_THRESHOLD: usize = 50;
pub struct ChatPanel {
rpc: Arc<Client>,
channel_list: ModelHandle<ChannelList>,
active_channel: Option<(ModelHandle<Channel>, Subscription)>,
message_list: ListState,
input_editor: ViewHandle<Editor>,
channel_select: ViewHandle<Select>,
local_timezone: UtcOffset,
_observe_status: Task<()>,
}
pub enum Event {}
actions!(chat_panel, [LoadMoreMessages]);
pub fn init(cx: &mut MutableAppContext) {
cx.add_action(ChatPanel::send);
cx.add_action(ChatPanel::load_more_messages);
}
impl ChatPanel {
pub fn new(
rpc: Arc<Client>,
channel_list: ModelHandle<ChannelList>,
cx: &mut ViewContext<Self>,
) -> Self {
let input_editor = cx.add_view(|cx| {
let mut editor =
Editor::auto_height(4, Some(|theme| theme.chat_panel.input_editor.clone()), cx);
editor.set_soft_wrap_mode(SoftWrap::EditorWidth, cx);
editor
});
let channel_select = cx.add_view(|cx| {
let channel_list = channel_list.clone();
Select::new(0, cx, {
move |ix, item_type, is_hovered, cx| {
Self::render_channel_name(
&channel_list,
ix,
item_type,
is_hovered,
&cx.global::<Settings>().theme.chat_panel.channel_select,
cx,
)
}
})
.with_style(move |cx| {
let theme = &cx.global::<Settings>().theme.chat_panel.channel_select;
SelectStyle {
header: theme.header.container,
menu: theme.menu,
}
})
});
let mut message_list = ListState::new(0, Orientation::Bottom, 1000., cx, {
let this = cx.weak_handle();
move |_, ix, cx| {
let this = this.upgrade(cx).unwrap().read(cx);
let message = this.active_channel.as_ref().unwrap().0.read(cx).message(ix);
this.render_message(message, cx)
}
});
message_list.set_scroll_handler(|visible_range, cx| {
if visible_range.start < MESSAGE_LOADING_THRESHOLD {
cx.dispatch_action(LoadMoreMessages);
}
});
let _observe_status = cx.spawn_weak(|this, mut cx| {
let mut status = rpc.status();
async move {
while (status.recv().await).is_some() {
if let Some(this) = this.upgrade(&cx) {
this.update(&mut cx, |_, cx| cx.notify());
} else {
break;
}
}
}
});
let mut this = Self {
rpc,
channel_list,
active_channel: Default::default(),
message_list,
input_editor,
channel_select,
local_timezone: cx.platform().local_timezone(),
_observe_status,
};
this.init_active_channel(cx);
cx.observe(&this.channel_list, |this, _, cx| {
this.init_active_channel(cx);
})
.detach();
cx.observe(&this.channel_select, |this, channel_select, cx| {
let selected_ix = channel_select.read(cx).selected_index();
let selected_channel = this.channel_list.update(cx, |channel_list, cx| {
let available_channels = channel_list.available_channels()?;
let channel_id = available_channels.get(selected_ix)?.id;
channel_list.get_channel(channel_id, cx)
});
if let Some(selected_channel) = selected_channel {
this.set_active_channel(selected_channel, cx);
}
})
.detach();
this
}
fn init_active_channel(&mut self, cx: &mut ViewContext<Self>) {
let (active_channel, channel_count) = self.channel_list.update(cx, |list, cx| {
let channel_count;
let mut active_channel = None;
if let Some(available_channels) = list.available_channels() {
channel_count = available_channels.len();
if self.active_channel.is_none() {
if let Some(channel_id) = available_channels.first().map(|channel| channel.id) {
active_channel = list.get_channel(channel_id, cx);
}
}
} else {
channel_count = 0;
}
(active_channel, channel_count)
});
if let Some(active_channel) = active_channel {
self.set_active_channel(active_channel, cx);
} else {
self.message_list.reset(0);
self.active_channel = None;
}
self.channel_select.update(cx, |select, cx| {
select.set_item_count(channel_count, cx);
});
}
fn set_active_channel(&mut self, channel: ModelHandle<Channel>, cx: &mut ViewContext<Self>) {
if self.active_channel.as_ref().map(|e| &e.0) != Some(&channel) {
{
let channel = channel.read(cx);
self.message_list.reset(channel.message_count());
let placeholder = format!("Message #{}", channel.name());
self.input_editor.update(cx, move |editor, cx| {
editor.set_placeholder_text(placeholder, cx);
});
}
let subscription = cx.subscribe(&channel, Self::channel_did_change);
self.active_channel = Some((channel, subscription));
}
}
fn channel_did_change(
&mut self,
_: ModelHandle<Channel>,
event: &ChannelEvent,
cx: &mut ViewContext<Self>,
) {
match event {
ChannelEvent::MessagesUpdated {
old_range,
new_count,
} => {
self.message_list.splice(old_range.clone(), *new_count);
}
}
cx.notify();
}
fn render_channel(&self, cx: &mut RenderContext<Self>) -> ElementBox {
let theme = &cx.global::<Settings>().theme;
Flex::column()
.with_child(
Container::new(ChildView::new(&self.channel_select).boxed())
.with_style(theme.chat_panel.channel_select.container)
.boxed(),
)
.with_child(self.render_active_channel_messages())
.with_child(self.render_input_box(cx))
.boxed()
}
fn render_active_channel_messages(&self) -> ElementBox {
let messages = if self.active_channel.is_some() {
List::new(self.message_list.clone()).boxed()
} else {
Empty::new().boxed()
};
FlexItem::new(messages).flex(1., true).boxed()
}
fn render_message(&self, message: &ChannelMessage, cx: &AppContext) -> ElementBox {
let now = OffsetDateTime::now_utc();
let settings = cx.global::<Settings>();
let theme = if message.is_pending() {
&settings.theme.chat_panel.pending_message
} else {
&settings.theme.chat_panel.message
};
Container::new(
Flex::column()
.with_child(
Flex::row()
.with_child(
Container::new(
Label::new(
message.sender.github_login.clone(),
theme.sender.text.clone(),
)
.boxed(),
)
.with_style(theme.sender.container)
.boxed(),
)
.with_child(
Container::new(
Label::new(
format_timestamp(message.timestamp, now, self.local_timezone),
theme.timestamp.text.clone(),
)
.boxed(),
)
.with_style(theme.timestamp.container)
.boxed(),
)
.boxed(),
)
.with_child(Text::new(message.body.clone(), theme.body.clone()).boxed())
.boxed(),
)
.with_style(theme.container)
.boxed()
}
fn render_input_box(&self, cx: &AppContext) -> ElementBox {
let theme = &cx.global::<Settings>().theme;
Container::new(ChildView::new(&self.input_editor).boxed())
.with_style(theme.chat_panel.input_editor.container)
.boxed()
}
fn render_channel_name(
channel_list: &ModelHandle<ChannelList>,
ix: usize,
item_type: ItemType,
is_hovered: bool,
theme: &theme::ChannelSelect,
cx: &AppContext,
) -> ElementBox {
let channel = &channel_list.read(cx).available_channels().unwrap()[ix];
let theme = match (item_type, is_hovered) {
(ItemType::Header, _) => &theme.header,
(ItemType::Selected, false) => &theme.active_item,
(ItemType::Selected, true) => &theme.hovered_active_item,
(ItemType::Unselected, false) => &theme.item,
(ItemType::Unselected, true) => &theme.hovered_item,
};
Container::new(
Flex::row()
.with_child(
Container::new(Label::new("#".to_string(), theme.hash.text.clone()).boxed())
.with_style(theme.hash.container)
.boxed(),
)
.with_child(Label::new(channel.name.clone(), theme.name.clone()).boxed())
.boxed(),
)
.with_style(theme.container)
.boxed()
}
fn render_sign_in_prompt(&self, cx: &mut RenderContext<Self>) -> ElementBox {
let theme = cx.global::<Settings>().theme.clone();
let rpc = self.rpc.clone();
let this = cx.handle();
enum SignInPromptLabel {}
Align::new(
MouseEventHandler::<SignInPromptLabel>::new(0, cx, |mouse_state, _| {
Label::new(
"Sign in to use chat".to_string(),
if mouse_state.hovered {
theme.chat_panel.hovered_sign_in_prompt.clone()
} else {
theme.chat_panel.sign_in_prompt.clone()
},
)
.boxed()
})
.with_cursor_style(CursorStyle::PointingHand)
.on_click(MouseButton::Left, move |_, cx| {
let rpc = rpc.clone();
let this = this.clone();
cx.spawn(|mut cx| async move {
if rpc
.authenticate_and_connect(true, &cx)
.log_err()
.await
.is_some()
{
cx.update(|cx| {
if let Some(this) = this.upgrade(cx) {
if this.is_focused(cx) {
this.update(cx, |this, cx| cx.focus(&this.input_editor));
}
}
})
}
})
.detach();
})
.boxed(),
)
.boxed()
}
fn send(&mut self, _: &Confirm, cx: &mut ViewContext<Self>) {
if let Some((channel, _)) = self.active_channel.as_ref() {
let body = self.input_editor.update(cx, |editor, cx| {
let body = editor.text(cx);
editor.clear(cx);
body
});
if let Some(task) = channel
.update(cx, |channel, cx| channel.send_message(body, cx))
.log_err()
{
task.detach();
}
}
}
fn load_more_messages(&mut self, _: &LoadMoreMessages, cx: &mut ViewContext<Self>) {
if let Some((channel, _)) = self.active_channel.as_ref() {
channel.update(cx, |channel, cx| {
channel.load_more_messages(cx);
})
}
}
}
impl Entity for ChatPanel {
type Event = Event;
}
impl View for ChatPanel {
fn ui_name() -> &'static str {
"ChatPanel"
}
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
let element = if self.rpc.user_id().is_some() {
self.render_channel(cx)
} else {
self.render_sign_in_prompt(cx)
};
let theme = &cx.global::<Settings>().theme;
ConstrainedBox::new(
Container::new(element)
.with_style(theme.chat_panel.container)
.boxed(),
)
.with_min_width(150.)
.boxed()
}
fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
if matches!(
*self.rpc.status().borrow(),
client::Status::Connected { .. }
) {
cx.focus(&self.input_editor);
}
}
}
fn format_timestamp(
mut timestamp: OffsetDateTime,
mut now: OffsetDateTime,
local_timezone: UtcOffset,
) -> String {
timestamp = timestamp.to_offset(local_timezone);
now = now.to_offset(local_timezone);
let today = now.date();
let date = timestamp.date();
let mut hour = timestamp.hour();
let mut part = "am";
if hour > 12 {
hour -= 12;
part = "pm";
}
if date == today {
format!("{:02}:{:02}{}", hour, timestamp.minute(), part)
} else if date.next_day() == Some(today) {
format!("yesterday at {:02}:{:02}{}", hour, timestamp.minute(), part)
} else {
format!("{:02}/{}/{}", date.month() as u32, date.day(), date.year())
}
}

View File

@@ -35,9 +35,11 @@ tiny_http = "0.8"
uuid = { version = "1.1.2", features = ["v4"] }
url = "2.2"
serde = { version = "*", features = ["derive"] }
settings = { path = "../settings" }
tempfile = "3"
[dev-dependencies]
collections = { path = "../collections", features = ["test-support"] }
gpui = { path = "../gpui", features = ["test-support"] }
rpc = { path = "../rpc", features = ["test-support"] }
settings = { path = "../settings", features = ["test-support"] }

View File

@@ -530,7 +530,7 @@ impl ChannelMessage {
) -> Result<Self> {
let sender = user_store
.update(cx, |user_store, cx| {
user_store.fetch_user(message.sender_id, cx)
user_store.get_user(message.sender_id, cx)
})
.await?;
Ok(ChannelMessage {

View File

@@ -13,11 +13,13 @@ use async_tungstenite::tungstenite::{
http::{Request, StatusCode},
};
use db::Db;
use futures::{future::LocalBoxFuture, FutureExt, SinkExt, StreamExt, TryStreamExt};
use futures::{future::LocalBoxFuture, AsyncReadExt, FutureExt, SinkExt, StreamExt, TryStreamExt};
use gpui::{
actions, serde_json::Value, AnyModelHandle, AnyViewHandle, AnyWeakModelHandle,
AnyWeakViewHandle, AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle,
MutableAppContext, Task, View, ViewContext, ViewHandle,
actions,
serde_json::{self, Value},
AnyModelHandle, AnyViewHandle, AnyWeakModelHandle, AnyWeakViewHandle, AppContext,
AsyncAppContext, Entity, ModelContext, ModelHandle, MutableAppContext, Task, View, ViewContext,
ViewHandle,
};
use http::HttpClient;
use lazy_static::lazy_static;
@@ -25,6 +27,8 @@ use parking_lot::RwLock;
use postage::watch;
use rand::prelude::*;
use rpc::proto::{AnyTypedEnvelope, EntityMessage, EnvelopedMessage, RequestMessage};
use serde::Deserialize;
use settings::ReleaseChannel;
use std::{
any::TypeId,
collections::HashMap,
@@ -50,9 +54,14 @@ lazy_static! {
pub static ref IMPERSONATE_LOGIN: Option<String> = std::env::var("ZED_IMPERSONATE")
.ok()
.and_then(|s| if s.is_empty() { None } else { Some(s) });
pub static ref ADMIN_API_TOKEN: Option<String> = std::env::var("ZED_ADMIN_API_TOKEN")
.ok()
.and_then(|s| if s.is_empty() { None } else { Some(s) });
}
pub const ZED_SECRET_CLIENT_TOKEN: &str = "618033988749894";
pub const INITIAL_RECONNECTION_DELAY: Duration = Duration::from_millis(100);
pub const CONNECTION_TIMEOUT: Duration = Duration::from_secs(5);
actions!(client, [Authenticate]);
@@ -141,11 +150,16 @@ pub enum Status {
Authenticating,
Connecting,
ConnectionError,
Connected { connection_id: ConnectionId },
Connected {
peer_id: PeerId,
connection_id: ConnectionId,
},
ConnectionLost,
Reauthenticating,
Reconnecting,
ReconnectionError { next_reconnection: Instant },
ReconnectionError {
next_reconnection: Instant,
},
}
impl Status {
@@ -312,6 +326,14 @@ impl Client {
.map(|credentials| credentials.user_id)
}
pub fn peer_id(&self) -> Option<PeerId> {
if let Status::Connected { peer_id, .. } = &*self.status().borrow() {
Some(*peer_id)
} else {
None
}
}
pub fn status(&self) -> watch::Receiver<Status> {
self.state.read().status.1.clone()
}
@@ -330,7 +352,7 @@ impl Client {
let reconnect_interval = state.reconnect_interval;
state._reconnect_task = Some(cx.spawn(|cx| async move {
let mut rng = StdRng::from_entropy();
let mut delay = Duration::from_millis(100);
let mut delay = INITIAL_RECONNECTION_DELAY;
while let Err(error) = this.authenticate_and_connect(true, &cx).await {
log::error!("failed to connect {}", error);
if matches!(*this.status().borrow(), Status::ConnectionError) {
@@ -351,7 +373,7 @@ impl Client {
}));
}
Status::SignedOut | Status::UpgradeRequired => {
self.telemetry.set_metrics_id(None);
self.telemetry.set_authenticated_user_info(None, false);
state._reconnect_task.take();
}
_ => {}
@@ -434,6 +456,29 @@ impl Client {
}
}
pub fn add_request_handler<M, E, H, F>(
self: &Arc<Self>,
model: ModelHandle<E>,
handler: H,
) -> Subscription
where
M: RequestMessage,
E: Entity,
H: 'static
+ Send
+ Sync
+ Fn(ModelHandle<E>, TypedEnvelope<M>, Arc<Self>, AsyncAppContext) -> F,
F: 'static + Future<Output = Result<M::Response>>,
{
self.add_message_handler(model, move |handle, envelope, this, cx| {
Self::respond_to_request(
envelope.receipt(),
handler(handle, envelope, this.clone(), cx),
this,
)
})
}
pub fn add_view_message_handler<M, E, H, F>(self: &Arc<Self>, handler: H)
where
M: EntityMessage,
@@ -638,46 +683,104 @@ impl Client {
self.set_status(Status::Reconnecting, cx);
}
match self.establish_connection(&credentials, cx).await {
Ok(conn) => {
self.state.write().credentials = Some(credentials.clone());
if !read_from_keychain && IMPERSONATE_LOGIN.is_none() {
write_credentials_to_keychain(&credentials, cx).log_err();
}
self.set_connection(conn, cx).await;
Ok(())
}
Err(EstablishConnectionError::Unauthorized) => {
self.state.write().credentials.take();
if read_from_keychain {
cx.platform().delete_credentials(&ZED_SERVER_URL).log_err();
self.set_status(Status::SignedOut, cx);
self.authenticate_and_connect(false, cx).await
} else {
self.set_status(Status::ConnectionError, cx);
Err(EstablishConnectionError::Unauthorized)?
let mut timeout = cx.background().timer(CONNECTION_TIMEOUT).fuse();
futures::select_biased! {
connection = self.establish_connection(&credentials, cx).fuse() => {
match connection {
Ok(conn) => {
self.state.write().credentials = Some(credentials.clone());
if !read_from_keychain && IMPERSONATE_LOGIN.is_none() {
write_credentials_to_keychain(&credentials, cx).log_err();
}
futures::select_biased! {
result = self.set_connection(conn, cx).fuse() => result,
_ = timeout => {
self.set_status(Status::ConnectionError, cx);
Err(anyhow!("timed out waiting on hello message from server"))
}
}
}
Err(EstablishConnectionError::Unauthorized) => {
self.state.write().credentials.take();
if read_from_keychain {
cx.platform().delete_credentials(&ZED_SERVER_URL).log_err();
self.set_status(Status::SignedOut, cx);
self.authenticate_and_connect(false, cx).await
} else {
self.set_status(Status::ConnectionError, cx);
Err(EstablishConnectionError::Unauthorized)?
}
}
Err(EstablishConnectionError::UpgradeRequired) => {
self.set_status(Status::UpgradeRequired, cx);
Err(EstablishConnectionError::UpgradeRequired)?
}
Err(error) => {
self.set_status(Status::ConnectionError, cx);
Err(error)?
}
}
}
Err(EstablishConnectionError::UpgradeRequired) => {
self.set_status(Status::UpgradeRequired, cx);
Err(EstablishConnectionError::UpgradeRequired)?
}
Err(error) => {
_ = &mut timeout => {
self.set_status(Status::ConnectionError, cx);
Err(error)?
Err(anyhow!("timed out trying to establish connection"))
}
}
}
async fn set_connection(self: &Arc<Self>, conn: Connection, cx: &AsyncAppContext) {
async fn set_connection(
self: &Arc<Self>,
conn: Connection,
cx: &AsyncAppContext,
) -> Result<()> {
let executor = cx.background();
log::info!("add connection to peer");
let (connection_id, handle_io, mut incoming) = self
.peer
.add_connection(conn, move |duration| executor.timer(duration))
.await;
log::info!("set status to connected {}", connection_id);
self.set_status(Status::Connected { connection_id }, cx);
.add_connection(conn, move |duration| executor.timer(duration));
let handle_io = cx.background().spawn(handle_io);
let peer_id = async {
log::info!("waiting for server hello");
let message = incoming
.next()
.await
.ok_or_else(|| anyhow!("no hello message received"))?;
log::info!("got server hello");
let hello_message_type_name = message.payload_type_name().to_string();
let hello = message
.into_any()
.downcast::<TypedEnvelope<proto::Hello>>()
.map_err(|_| {
anyhow!(
"invalid hello message received: {:?}",
hello_message_type_name
)
})?;
Ok(PeerId(hello.payload.peer_id))
};
let peer_id = match peer_id.await {
Ok(peer_id) => peer_id,
Err(error) => {
self.peer.disconnect(connection_id);
return Err(error);
}
};
log::info!(
"set status to connected (connection id: {}, peer id: {})",
connection_id,
peer_id
);
self.set_status(
Status::Connected {
peer_id,
connection_id,
},
cx,
);
cx.foreground()
.spawn({
let cx = cx.clone();
@@ -726,11 +829,14 @@ impl Client {
continue;
};
if let Some(handler) = state.message_handlers.get(&payload_type_id).cloned()
{
drop(state); // Avoid deadlocks if the handler interacts with rpc::Client
let future = handler(model, message, &this, cx.clone());
let handler = state.message_handlers.get(&payload_type_id).cloned();
// Dropping the state prevents deadlocks if the handler interacts with rpc::Client.
// It also ensures we don't hold the lock while yielding back to the executor, as
// that might cause the executor thread driving this future to block indefinitely.
drop(state);
if let Some(handler) = handler {
let future = handler(model, message, &this, cx.clone());
let client_id = this.id;
log::debug!(
"rpc message received. client_id:{}, message_id:{}, sender_id:{:?}, type:{}",
@@ -775,14 +881,18 @@ impl Client {
})
.detach();
let handle_io = cx.background().spawn(handle_io);
let this = self.clone();
let cx = cx.clone();
cx.foreground()
.spawn(async move {
match handle_io.await {
Ok(()) => {
if *this.status().borrow() == (Status::Connected { connection_id }) {
if *this.status().borrow()
== (Status::Connected {
connection_id,
peer_id,
})
{
this.set_status(Status::SignedOut, &cx);
}
}
@@ -793,6 +903,8 @@ impl Client {
}
})
.detach();
Ok(())
}
fn authenticate(self: &Arc<Self>, cx: &AsyncAppContext) -> Task<Result<Credentials>> {
@@ -817,11 +929,51 @@ impl Client {
self.establish_websocket_connection(credentials, cx)
}
async fn get_rpc_url(http: Arc<dyn HttpClient>, is_preview: bool) -> Result<Url> {
let preview_param = if is_preview { "?preview=1" } else { "" };
let url = format!("{}/rpc{preview_param}", *ZED_SERVER_URL);
let response = http.get(&url, Default::default(), false).await?;
// Normally, ZED_SERVER_URL is set to the URL of zed.dev website.
// The website's /rpc endpoint redirects to a collab server's /rpc endpoint,
// which requires authorization via an HTTP header.
//
// For testing purposes, ZED_SERVER_URL can also set to the direct URL of
// of a collab server. In that case, a request to the /rpc endpoint will
// return an 'unauthorized' response.
let collab_url = if response.status().is_redirection() {
response
.headers()
.get("Location")
.ok_or_else(|| anyhow!("missing location header in /rpc response"))?
.to_str()
.map_err(EstablishConnectionError::other)?
.to_string()
} else if response.status() == StatusCode::UNAUTHORIZED {
url
} else {
Err(anyhow!(
"unexpected /rpc response status {}",
response.status()
))?
};
Url::parse(&collab_url).context("invalid rpc url")
}
fn establish_websocket_connection(
self: &Arc<Self>,
credentials: &Credentials,
cx: &AsyncAppContext,
) -> Task<Result<Connection, EstablishConnectionError>> {
let is_preview = cx.read(|cx| {
if cx.has_global::<ReleaseChannel>() {
*cx.global::<ReleaseChannel>() == ReleaseChannel::Preview
} else {
false
}
});
let request = Request::builder()
.header(
"Authorization",
@@ -831,28 +983,7 @@ impl Client {
let http = self.http.clone();
cx.background().spawn(async move {
let mut rpc_url = format!("{}/rpc", *ZED_SERVER_URL);
let rpc_response = http.get(&rpc_url, Default::default(), false).await?;
if rpc_response.status().is_redirection() {
rpc_url = rpc_response
.headers()
.get("Location")
.ok_or_else(|| anyhow!("missing location header in /rpc response"))?
.to_str()
.map_err(EstablishConnectionError::other)?
.to_string();
}
// Until we switch the zed.dev domain to point to the new Next.js app, there
// will be no redirect required, and the app will connect directly to
// wss://zed.dev/rpc.
else if rpc_response.status() != StatusCode::UPGRADE_REQUIRED {
Err(anyhow!(
"unexpected /rpc response status {}",
rpc_response.status()
))?
}
let mut rpc_url = Url::parse(&rpc_url).context("invalid rpc url")?;
let mut rpc_url = Self::get_rpc_url(http, is_preview).await?;
let rpc_host = rpc_url
.host_str()
.zip(rpc_url.port_or_known_default())
@@ -895,6 +1026,7 @@ impl Client {
let platform = cx.platform();
let executor = cx.background();
let telemetry = self.telemetry.clone();
let http = self.http.clone();
executor.clone().spawn(async move {
// Generate a pair of asymmetric encryption keys. The public key will be used by the
// zed server to encrypt the user's access token, so that it can'be intercepted by
@@ -904,6 +1036,10 @@ impl Client {
let public_key_string =
String::try_from(public_key).expect("failed to serialize public key for auth");
if let Some((login, token)) = IMPERSONATE_LOGIN.as_ref().zip(ADMIN_API_TOKEN.as_ref()) {
return Self::authenticate_as_admin(http, login.clone(), token.clone()).await;
}
// Start an HTTP server to receive the redirect from Zed's sign-in page.
let server = tiny_http::Server::http("127.0.0.1:0").expect("failed to find open port");
let port = server.server_addr().port();
@@ -982,6 +1118,50 @@ impl Client {
})
}
async fn authenticate_as_admin(
http: Arc<dyn HttpClient>,
login: String,
mut api_token: String,
) -> Result<Credentials> {
#[derive(Deserialize)]
struct AuthenticatedUserResponse {
user: User,
}
#[derive(Deserialize)]
struct User {
id: u64,
}
// Use the collab server's admin API to retrieve the id
// of the impersonated user.
let mut url = Self::get_rpc_url(http.clone(), false).await?;
url.set_path("/user");
url.set_query(Some(&format!("github_login={login}")));
let request = Request::get(url.as_str())
.header("Authorization", format!("token {api_token}"))
.body("".into())?;
let mut response = http.send(request).await?;
let mut body = String::new();
response.body_mut().read_to_string(&mut body).await?;
if !response.status().is_success() {
Err(anyhow!(
"admin user request failed {} - {}",
response.status().as_u16(),
body,
))?;
}
let response: AuthenticatedUserResponse = serde_json::from_str(&body)?;
// Use the admin API token to authenticate as the impersonated user.
api_token.insert_str(0, "ADMIN_TOKEN:");
Ok(Credentials {
user_id: response.user.id,
access_token: api_token,
})
}
pub fn disconnect(self: &Arc<Self>, cx: &AsyncAppContext) -> Result<()> {
let conn_id = self.connection_id()?;
self.peer.disconnect(conn_id);
@@ -1040,12 +1220,12 @@ impl Client {
self.peer.respond_with_error(receipt, error)
}
pub fn start_telemetry(&self, db: Arc<Db>) {
self.telemetry.start(db);
pub fn start_telemetry(&self, db: Db) {
self.telemetry.start(db.clone());
}
pub fn report_event(&self, kind: &str, properties: Value) {
self.telemetry.report_event(kind, properties)
self.telemetry.report_event(kind, properties.clone());
}
pub fn telemetry_log_file_path(&self) -> Option<PathBuf> {
@@ -1146,6 +1326,76 @@ mod tests {
assert_eq!(server.auth_count(), 2); // Client re-authenticated due to an invalid token
}
#[gpui::test(iterations = 10)]
async fn test_connection_timeout(deterministic: Arc<Deterministic>, cx: &mut TestAppContext) {
deterministic.forbid_parking();
let user_id = 5;
let client = cx.update(|cx| Client::new(FakeHttpClient::with_404_response(), cx));
let mut status = client.status();
// Time out when client tries to connect.
client.override_authenticate(move |cx| {
cx.foreground().spawn(async move {
Ok(Credentials {
user_id,
access_token: "token".into(),
})
})
});
client.override_establish_connection(|_, cx| {
cx.foreground().spawn(async move {
future::pending::<()>().await;
unreachable!()
})
});
let auth_and_connect = cx.spawn({
let client = client.clone();
|cx| async move { client.authenticate_and_connect(false, &cx).await }
});
deterministic.run_until_parked();
assert!(matches!(status.next().await, Some(Status::Connecting)));
deterministic.advance_clock(CONNECTION_TIMEOUT);
assert!(matches!(
status.next().await,
Some(Status::ConnectionError { .. })
));
auth_and_connect.await.unwrap_err();
// Allow the connection to be established.
let server = FakeServer::for_client(user_id, &client, cx).await;
assert!(matches!(
status.next().await,
Some(Status::Connected { .. })
));
// Disconnect client.
server.forbid_connections();
server.disconnect();
while !matches!(status.next().await, Some(Status::ReconnectionError { .. })) {}
// Time out when re-establishing the connection.
server.allow_connections();
client.override_establish_connection(|_, cx| {
cx.foreground().spawn(async move {
future::pending::<()>().await;
unreachable!()
})
});
deterministic.advance_clock(2 * INITIAL_RECONNECTION_DELAY);
assert!(matches!(
status.next().await,
Some(Status::Reconnecting { .. })
));
deterministic.advance_clock(CONNECTION_TIMEOUT);
assert!(matches!(
status.next().await,
Some(Status::ReconnectionError { .. })
));
}
#[gpui::test(iterations = 10)]
async fn test_authenticating_more_than_once(
cx: &mut TestAppContext,

View File

@@ -9,6 +9,8 @@ use isahc::Request;
use lazy_static::lazy_static;
use parking_lot::Mutex;
use serde::Serialize;
use serde_json::json;
use settings::ReleaseChannel;
use std::{
io::Write,
mem,
@@ -23,7 +25,6 @@ use uuid::Uuid;
pub struct Telemetry {
http_client: Arc<dyn HttpClient>,
executor: Arc<Background>,
session_id: u128,
state: Mutex<TelemetryState>,
}
@@ -32,50 +33,62 @@ struct TelemetryState {
metrics_id: Option<Arc<str>>,
device_id: Option<Arc<str>>,
app_version: Option<Arc<str>>,
release_channel: Option<&'static str>,
os_version: Option<Arc<str>>,
os_name: &'static str,
queue: Vec<AmplitudeEvent>,
queue: Vec<MixpanelEvent>,
next_event_id: usize,
flush_task: Option<Task<()>>,
log_file: Option<NamedTempFile>,
}
const AMPLITUDE_EVENTS_URL: &'static str = "https://api2.amplitude.com/batch";
const MIXPANEL_EVENTS_URL: &'static str = "https://api.mixpanel.com/track";
const MIXPANEL_ENGAGE_URL: &'static str = "https://api.mixpanel.com/engage#profile-set";
lazy_static! {
static ref AMPLITUDE_API_KEY: Option<String> = std::env::var("ZED_AMPLITUDE_API_KEY")
static ref MIXPANEL_TOKEN: Option<String> = std::env::var("ZED_MIXPANEL_TOKEN")
.ok()
.or_else(|| option_env!("ZED_AMPLITUDE_API_KEY").map(|key| key.to_string()));
.or_else(|| option_env!("ZED_MIXPANEL_TOKEN").map(|key| key.to_string()));
}
#[derive(Serialize)]
struct AmplitudeEventBatch {
api_key: &'static str,
events: Vec<AmplitudeEvent>,
options: AmplitudeEventBatchOptions,
#[derive(Serialize, Debug)]
struct MixpanelEvent {
event: String,
properties: MixpanelEventProperties,
}
#[derive(Serialize)]
struct AmplitudeEventBatchOptions {
min_id_length: usize,
}
#[derive(Serialize)]
struct AmplitudeEvent {
#[serde(skip_serializing_if = "Option::is_none")]
user_id: Option<Arc<str>>,
device_id: Option<Arc<str>>,
event_type: String,
#[serde(skip_serializing_if = "Option::is_none")]
event_properties: Option<Map<String, Value>>,
#[serde(skip_serializing_if = "Option::is_none")]
user_properties: Option<Map<String, Value>>,
os_name: &'static str,
os_version: Option<Arc<str>>,
app_version: Option<Arc<str>>,
event_id: usize,
session_id: u128,
#[derive(Serialize, Debug)]
struct MixpanelEventProperties {
// Mixpanel required fields
#[serde(skip_serializing_if = "str::is_empty")]
token: &'static str,
time: u128,
distinct_id: Option<Arc<str>>,
#[serde(rename = "$insert_id")]
insert_id: usize,
// Custom fields
#[serde(skip_serializing_if = "Option::is_none", flatten)]
event_properties: Option<Map<String, Value>>,
#[serde(rename = "OS Name")]
os_name: &'static str,
#[serde(rename = "OS Version")]
os_version: Option<Arc<str>>,
#[serde(rename = "Release Channel")]
release_channel: Option<&'static str>,
#[serde(rename = "App Version")]
app_version: Option<Arc<str>>,
#[serde(rename = "Signed In")]
signed_in: bool,
}
#[derive(Serialize)]
struct MixpanelEngageRequest {
#[serde(rename = "$token")]
token: &'static str,
#[serde(rename = "$distinct_id")]
distinct_id: Arc<str>,
#[serde(rename = "$set")]
set: Value,
}
#[cfg(debug_assertions)]
@@ -93,33 +106,29 @@ const DEBOUNCE_INTERVAL: Duration = Duration::from_secs(30);
impl Telemetry {
pub fn new(client: Arc<dyn HttpClient>, cx: &AppContext) -> Arc<Self> {
let platform = cx.platform();
let release_channel = if cx.has_global::<ReleaseChannel>() {
Some(cx.global::<ReleaseChannel>().name())
} else {
None
};
let this = Arc::new(Self {
http_client: client,
executor: cx.background().clone(),
session_id: SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_millis(),
state: Mutex::new(TelemetryState {
os_version: platform
.os_version()
.log_err()
.map(|v| v.to_string().into()),
os_version: platform.os_version().ok().map(|v| v.to_string().into()),
os_name: platform.os_name().into(),
app_version: platform
.app_version()
.log_err()
.map(|v| v.to_string().into()),
app_version: platform.app_version().ok().map(|v| v.to_string().into()),
release_channel,
device_id: None,
metrics_id: None,
queue: Default::default(),
flush_task: Default::default(),
next_event_id: 0,
log_file: None,
metrics_id: None,
}),
});
if AMPLITUDE_API_KEY.is_some() {
if MIXPANEL_TOKEN.is_some() {
this.executor
.spawn({
let this = this.clone();
@@ -139,30 +148,27 @@ impl Telemetry {
Some(self.state.lock().log_file.as_ref()?.path().to_path_buf())
}
pub fn start(self: &Arc<Self>, db: Arc<Db>) {
pub fn start(self: &Arc<Self>, db: Db) {
let this = self.clone();
self.executor
.spawn(
async move {
let device_id = if let Some(device_id) = db
.read(["device_id"])?
.into_iter()
.flatten()
.next()
.and_then(|bytes| String::from_utf8(bytes).ok())
{
let device_id = if let Ok(Some(device_id)) = db.read_kvp("device_id") {
device_id
} else {
let device_id = Uuid::new_v4().to_string();
db.write([("device_id", device_id.as_bytes())])?;
db.write_kvp("device_id", &device_id)?;
device_id
};
let device_id = Some(Arc::from(device_id));
let device_id: Arc<str> = device_id.into();
let mut state = this.state.lock();
state.device_id = device_id.clone();
state.device_id = Some(device_id.clone());
for event in &mut state.queue {
event.device_id = device_id.clone();
event
.properties
.distinct_id
.get_or_insert_with(|| device_id.clone());
}
if !state.queue.is_empty() {
drop(state);
@@ -176,35 +182,66 @@ impl Telemetry {
.detach();
}
pub fn set_metrics_id(&self, metrics_id: Option<String>) {
self.state.lock().metrics_id = metrics_id.map(|s| s.into());
pub fn set_authenticated_user_info(
self: &Arc<Self>,
metrics_id: Option<String>,
is_staff: bool,
) {
let this = self.clone();
let mut state = self.state.lock();
let device_id = state.device_id.clone();
let metrics_id: Option<Arc<str>> = metrics_id.map(|id| id.into());
state.metrics_id = metrics_id.clone();
drop(state);
if let Some((token, device_id)) = MIXPANEL_TOKEN.as_ref().zip(device_id) {
self.executor
.spawn(
async move {
let json_bytes = serde_json::to_vec(&[MixpanelEngageRequest {
token,
distinct_id: device_id,
set: json!({
"Staff": is_staff,
"ID": metrics_id,
"App": true
}),
}])?;
let request = Request::post(MIXPANEL_ENGAGE_URL)
.header("Content-Type", "application/json")
.body(json_bytes.into())?;
this.http_client.send(request).await?;
Ok(())
}
.log_err(),
)
.detach();
}
}
pub fn report_event(self: &Arc<Self>, kind: &str, properties: Value) {
if AMPLITUDE_API_KEY.is_none() {
return;
}
let mut state = self.state.lock();
let event = AmplitudeEvent {
event_type: kind.to_string(),
time: SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_millis(),
session_id: self.session_id,
event_properties: if let Value::Object(properties) = properties {
Some(properties)
} else {
None
let event = MixpanelEvent {
event: kind.to_string(),
properties: MixpanelEventProperties {
token: "",
time: SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_millis(),
distinct_id: state.device_id.clone(),
insert_id: post_inc(&mut state.next_event_id),
event_properties: if let Value::Object(properties) = properties {
Some(properties)
} else {
None
},
os_name: state.os_name,
os_version: state.os_version.clone(),
release_channel: state.release_channel,
app_version: state.app_version.clone(),
signed_in: state.metrics_id.is_some(),
},
user_properties: None,
user_id: state.metrics_id.clone(),
device_id: state.device_id.clone(),
os_name: state.os_name,
os_version: state.os_version.clone(),
app_version: state.app_version.clone(),
event_id: post_inc(&mut state.next_event_id),
};
state.queue.push(event);
if state.device_id.is_some() {
@@ -224,11 +261,11 @@ impl Telemetry {
fn flush(self: &Arc<Self>) {
let mut state = self.state.lock();
let events = mem::take(&mut state.queue);
let mut events = mem::take(&mut state.queue);
state.flush_task.take();
drop(state);
if let Some(api_key) = AMPLITUDE_API_KEY.as_ref() {
if let Some(token) = MIXPANEL_TOKEN.as_ref() {
let this = self.clone();
self.executor
.spawn(
@@ -237,23 +274,21 @@ impl Telemetry {
if let Some(file) = &mut this.state.lock().log_file {
let file = file.as_file_mut();
for event in &events {
for event in &mut events {
json_bytes.clear();
serde_json::to_writer(&mut json_bytes, event)?;
file.write_all(&json_bytes)?;
file.write(b"\n")?;
event.properties.token = token;
}
}
let batch = AmplitudeEventBatch {
api_key,
events,
options: AmplitudeEventBatchOptions { min_id_length: 1 },
};
json_bytes.clear();
serde_json::to_writer(&mut json_bytes, &batch)?;
let request =
Request::post(AMPLITUDE_EVENTS_URL).body(json_bytes.into())?;
serde_json::to_writer(&mut json_bytes, &events)?;
let request = Request::post(MIXPANEL_EVENTS_URL)
.header("Content-Type", "application/json")
.body(json_bytes.into())?;
this.http_client.send(request).await?;
Ok(())
}

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