From d9e4c1bfda89acbda9982ac2334703bbbef4ba58 Mon Sep 17 00:00:00 2001 From: Alistair Smith Date: Sun, 17 Nov 2024 22:49:10 -0800 Subject: [PATCH 01/10] loose initial keyboard shortcuts setup --- src/ui/src/actions.rs | 3 +++ src/ui/src/main.rs | 11 +++++++++++ src/ui/src/menu.rs | 10 ++++++++++ 3 files changed, 24 insertions(+) create mode 100644 src/ui/src/actions.rs create mode 100644 src/ui/src/menu.rs diff --git a/src/ui/src/actions.rs b/src/ui/src/actions.rs new file mode 100644 index 0000000..2b0163a --- /dev/null +++ b/src/ui/src/actions.rs @@ -0,0 +1,3 @@ +use gpui::actions; + +actions!(scope, [Quit]); diff --git a/src/ui/src/main.rs b/src/ui/src/main.rs index 0c7601f..5ccd67a 100644 --- a/src/ui/src/main.rs +++ b/src/ui/src/main.rs @@ -1,6 +1,8 @@ +pub mod actions; pub mod app; pub mod app_state; pub mod channel; +pub mod menu; use std::sync::Arc; @@ -8,6 +10,7 @@ use app_state::AppState; use components::theme::{Theme, ThemeColor, ThemeMode}; use gpui::*; use http_client::anyhow; +use menu::app_menus; #[derive(rust_embed::RustEmbed)] #[folder = "../../assets"] @@ -33,6 +36,10 @@ fn init(_: Arc, cx: &mut AppContext) -> Result<()> { Ok(()) } +fn quit(_: &actions::Quit, cx: &mut AppContext) { + cx.quit(); +} + #[tokio::main] async fn main() { env_logger::init(); @@ -47,6 +54,10 @@ async fn main() { return; } + cx.bind_keys(vec![KeyBinding::new("cmd-q", actions::Quit, None)]); + cx.on_action(quit); + cx.set_menus(app_menus()); + let mut theme = Theme::from(ThemeColor::dark()); theme.mode = ThemeMode::Dark; theme.accent = hsla(335.0 / 360.0, 97.0 / 100.0, 61.0 / 100.0, 1.0); diff --git a/src/ui/src/menu.rs b/src/ui/src/menu.rs new file mode 100644 index 0000000..1d03d7c --- /dev/null +++ b/src/ui/src/menu.rs @@ -0,0 +1,10 @@ +use gpui::{Menu, MenuItem}; + +use crate::actions; + +pub fn app_menus() -> Vec { + vec![Menu { + name: "Scope".into(), + items: vec![MenuItem::action("Quit", actions::Quit)], + }] +} From 954cc67193419725147c1ee59a3c18eeeb83500c Mon Sep 17 00:00:00 2001 From: circular Date: Mon, 18 Nov 2024 21:26:26 +1100 Subject: [PATCH 02/10] make bg adhere to the theme --- src/ui/src/app.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ui/src/app.rs b/src/ui/src/app.rs index 13b4115..54449bb 100644 --- a/src/ui/src/app.rs +++ b/src/ui/src/app.rs @@ -1,3 +1,4 @@ +use components::theme::ActiveTheme; use gpui::{div, img, rgb, Context, Model, ParentElement, Render, Styled, View, ViewContext, VisualContext}; use scope_backend_discord::{channel::DiscordChannel, client::DiscordClient, message::DiscordMessage, snowflake::Snowflake}; @@ -55,6 +56,6 @@ impl Render for App { let title_bar = components::TitleBar::new() .child(div().flex().flex_row().text_color(rgb(0xFFFFFF)).gap_2().child(img("brand/scope-round-200.png").w_6().h_6()).child("Scope")); - div().bg(rgb(0x16171B)).w_full().h_full().flex().flex_col().child(title_bar).child(content) + div().bg(cx.theme().background).w_full().h_full().flex().flex_col().child(title_bar).child(content) } } From 4ada314a68d3683d072db9efcb8c39ad02a43cea Mon Sep 17 00:00:00 2001 From: circular Date: Mon, 18 Nov 2024 21:39:00 +1100 Subject: [PATCH 03/10] use hsl() instead of hsla() --- src/ui/src/main.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ui/src/main.rs b/src/ui/src/main.rs index 5ccd67a..e7b9e86 100644 --- a/src/ui/src/main.rs +++ b/src/ui/src/main.rs @@ -7,7 +7,7 @@ pub mod menu; use std::sync::Arc; use app_state::AppState; -use components::theme::{Theme, ThemeColor, ThemeMode}; +use components::theme::{hsl, Theme, ThemeColor, ThemeMode}; use gpui::*; use http_client::anyhow; use menu::app_menus; @@ -60,8 +60,9 @@ async fn main() { let mut theme = Theme::from(ThemeColor::dark()); theme.mode = ThemeMode::Dark; - theme.accent = hsla(335.0 / 360.0, 97.0 / 100.0, 61.0 / 100.0, 1.0); - theme.title_bar = hsla(335.0 / 360.0, 97.0 / 100.0, 61.0 / 100.0, 1.0); + theme.accent = hsl(335.0, 97.0, 61.0); + theme.title_bar = hsl(335.0, 97.0, 61.0); + theme.background = hsl(225.0, 12.0, 10.0); cx.set_global(theme); cx.refresh(); From ea5f6463350ac0676e8a86cdb235259943f893b5 Mon Sep 17 00:00:00 2001 From: Aubrey Taylor Date: Mon, 18 Nov 2024 21:38:34 -0600 Subject: [PATCH 04/10] stop blocking on serenity::Client::start --- src/discord/src/client.rs | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/discord/src/client.rs b/src/discord/src/client.rs index 3481dcf..4aa2781 100644 --- a/src/discord/src/client.rs +++ b/src/discord/src/client.rs @@ -1,27 +1,30 @@ use std::{ - collections::HashMap, - sync::{Arc, OnceLock}, + collections::HashMap, sync::{Arc, OnceLock} }; use serenity::{ - all::{ChannelId, Context, CreateMessage, Event, EventHandler, GatewayIntents, Message, Nonce, RawEventHandler}, - async_trait, + all::{Cache, ChannelId, Context, CreateMessage, Event, EventHandler, GatewayIntents, Http, Message, Nonce, RawEventHandler}, async_trait }; use tokio::sync::{broadcast, RwLock}; use crate::{ message::{ - author::{DiscordMessageAuthor, DisplayName}, - content::DiscordMessageContent, - DiscordMessage, - }, - snowflake::Snowflake, + author::{DiscordMessageAuthor, DisplayName}, content::DiscordMessageContent, DiscordMessage + }, snowflake::Snowflake }; +#[allow(dead_code)] +struct SerenityClient { + // enable this when we enable the serenity[voice] feature + // voice_manager: Option> + http: Arc, + cache: Arc, +} + #[derive(Default)] pub struct DiscordClient { channel_message_event_handlers: RwLock>>>, - client: OnceLock, + client: OnceLock, user: OnceLock, } @@ -35,16 +38,22 @@ impl DiscordClient { .await .expect("Error creating client"); - if let Err(why) = discord.start().await { - panic!("Client error: {why:?}"); - } + let _ = client.client.set(SerenityClient { + // voice_manager: discord.voice_manager.clone(), + cache: discord.cache.clone(), + http: discord.http.clone(), + }); - let _ = client.client.set(discord); + tokio::spawn(async move { + if let Err(why) = discord.start().await { + panic!("Client error: {why:?}"); + } + }); client } - fn discord(&self) -> &serenity::Client { + fn discord(&self) -> &SerenityClient { self.client.get().unwrap() } From f6e8ab9111f23c9e504acd7b475bfd86da5b9847 Mon Sep 17 00:00:00 2001 From: Christian Bergschneider Date: Mon, 18 Nov 2024 22:17:41 +0100 Subject: [PATCH 05/10] feat: show message timestamp next to the top message that is grouped --- .editorconfig | 10 ++++++++++ Cargo.lock | 3 +++ Cargo.toml | 1 + src/chat/Cargo.toml | 1 + src/chat/src/message.rs | 2 ++ src/discord/Cargo.toml | 1 + src/discord/src/message/mod.rs | 7 +++++++ src/ui/Cargo.toml | 1 + src/ui/src/channel/message.rs | 20 ++++++++++++++++++-- 9 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f21c5ca --- /dev/null +++ b/.editorconfig @@ -0,0 +1,10 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +insert_final_newline = true +tab_width = 2 +indent_size = 2 +trim_trailing_whitespace = true \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 8f125f5..ec2e2e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5432,6 +5432,7 @@ dependencies = [ name = "scope" version = "0.1.0" dependencies = [ + "chrono", "dotenv", "env_logger", "gpui", @@ -5450,6 +5451,7 @@ dependencies = [ name = "scope-backend-discord" version = "0.1.0" dependencies = [ + "chrono", "gpui", "scope-chat", "serenity", @@ -5460,6 +5462,7 @@ dependencies = [ name = "scope-chat" version = "0.1.0" dependencies = [ + "chrono", "gpui", "tokio", ] diff --git a/Cargo.toml b/Cargo.toml index 2eeb65f..0d86827 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,3 +5,4 @@ members = [ ] [workspace.dependencies] +chrono = "0.4.38" \ No newline at end of file diff --git a/src/chat/Cargo.toml b/src/chat/Cargo.toml index d9d20c9..ec2e762 100644 --- a/src/chat/Cargo.toml +++ b/src/chat/Cargo.toml @@ -9,3 +9,4 @@ gpui = { git = "https://github.com/huacnlee/zed.git", branch = "export-platform- "font-kit", ] } tokio = "1.41.1" +chrono.workspace = true diff --git a/src/chat/src/message.rs b/src/chat/src/message.rs index 9b93b52..f805b36 100644 --- a/src/chat/src/message.rs +++ b/src/chat/src/message.rs @@ -1,3 +1,4 @@ +use chrono::{DateTime, Utc}; use gpui::Element; pub trait Message: Clone { @@ -6,6 +7,7 @@ pub trait Message: Clone { fn get_identifier(&self) -> String; fn get_nonce(&self) -> Option<&String>; fn should_group(&self, previous: &Self) -> bool; + fn get_timestamp(&self) -> Option>; } pub trait MessageAuthor: PartialEq + Eq { diff --git a/src/discord/Cargo.toml b/src/discord/Cargo.toml index f8882ec..417daef 100644 --- a/src/discord/Cargo.toml +++ b/src/discord/Cargo.toml @@ -11,3 +11,4 @@ gpui = { git = "https://github.com/huacnlee/zed.git", branch = "export-platform- scope-chat = { version = "0.1.0", path = "../chat" } serenity = { git = "https://github.com/scopeclient/serenity", version = "0.13.0" } tokio = "1.41.1" +chrono.workspace = true diff --git a/src/discord/src/message/mod.rs b/src/discord/src/message/mod.rs index 36a8e20..8195696 100644 --- a/src/discord/src/message/mod.rs +++ b/src/discord/src/message/mod.rs @@ -1,3 +1,4 @@ +use chrono::{DateTime, Utc}; use author::DiscordMessageAuthor; use content::DiscordMessageContent; use gpui::{Element, IntoElement}; @@ -39,4 +40,10 @@ impl Message for DiscordMessage { self.creation_time.signed_duration_since(*previous.creation_time).num_seconds() <= MAX_DISCORD_MESSAGE_GAP_SECS_FOR_GROUP } + + fn get_timestamp(&self) -> Option> { + let ts = self.creation_time.timestamp_millis(); + + DateTime::from_timestamp_millis(ts) + } } diff --git a/src/ui/Cargo.toml b/src/ui/Cargo.toml index 1dfbc21..924cc19 100644 --- a/src/ui/Cargo.toml +++ b/src/ui/Cargo.toml @@ -28,6 +28,7 @@ components = { package = "ui", git = "https://github.com/longbridgeapp/gpui-comp log = "0.4.22" random-string = "1.1.0" rust-embed = "8.5.0" +chrono.workspace = true [features] default = ["gpui/x11"] diff --git a/src/ui/src/channel/message.rs b/src/ui/src/channel/message.rs index 1032f8a..0891abe 100644 --- a/src/ui/src/channel/message.rs +++ b/src/ui/src/channel/message.rs @@ -1,4 +1,6 @@ use gpui::{div, img, rgb, Element, IntoElement, ParentElement, Styled}; +use gpui::prelude::FluentBuilder; +use chrono::Local; use scope_chat::message::{Message, MessageAuthor}; #[derive(Clone)] @@ -24,7 +26,7 @@ impl MessageGroup { self.contents.push(message); } - pub fn contents(&self) -> impl IntoIterator { + pub fn contents(&self) -> impl IntoIterator { self.contents.iter().map(|v| v.get_content()) } @@ -71,7 +73,21 @@ pub fn message(message: MessageGroup) -> impl IntoElement { .flex_col() // enabling this, and thus enabling ellipsis causes a consistent panic!? // .child(div().text_ellipsis().min_w_0().child(message.get_author().get_display_name())) - .child(div().min_w_0().child(message.get_author().get_display_name())) + .child( + div() + .min_w_0() + .flex() + .gap_2() + .child(message.get_author().get_display_name()) + .when_some(message.last().get_timestamp(), |d, ts| { + d.child( + div() + .min_w_0() + .text_color(rgb(0xAFBAC7)) + .text_sm() + .child(ts.with_timezone(&Local).format("%I:%M %p").to_string())) + }) + ) .children(message.contents()), ) } From c48a395b69c524fe5399c1b6195b0e67cd780933 Mon Sep 17 00:00:00 2001 From: Alistair Smith Date: Mon, 18 Nov 2024 20:14:17 -0800 Subject: [PATCH 06/10] chore: rm .editorconfig --- .editorconfig | 10 ---------- .gitignore | 3 ++- 2 files changed, 2 insertions(+), 11 deletions(-) delete mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index f21c5ca..0000000 --- a/.editorconfig +++ /dev/null @@ -1,10 +0,0 @@ -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_style = space -insert_final_newline = true -tab_width = 2 -indent_size = 2 -trim_trailing_whitespace = true \ No newline at end of file diff --git a/.gitignore b/.gitignore index 5df70c4..0b428cd 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ .vscode .DS_Store .direnv -.env \ No newline at end of file +.env +.editorconfig \ No newline at end of file From c8d07d0c851a592de1187058b5d1f5ae5b16c6ca Mon Sep 17 00:00:00 2001 From: PandaDEV <70103896+0PandaDEV@users.noreply.github.com> Date: Tue, 19 Nov 2024 14:50:17 +1000 Subject: [PATCH 07/10] macOS Code Signing & Local build scripts & Improved Issue template (#25) * chore: add macos build script * chore: linux and windows build scripts * chore(actions): code singing for macos * chore(actions): fix build error on silicon * feat: issue templates as yml * fix: remove print certificate * feat: openssl for password and hardcode bundle id * fix: typo --------- Co-authored-by: Alistair Smith --- .github/ISSUE_TEMPLATE/bug_report.md | 31 -------- .github/ISSUE_TEMPLATE/bug_report.yml | 65 ++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 ----- .github/ISSUE_TEMPLATE/feature_request.yml | 38 +++++++++ .github/workflows/build.yml | 51 ++++++++++++- .scripts/linux.sh | 43 +++++++++++ .scripts/macOS.sh | 89 ++++++++++++++++++++++ .scripts/windows.bat | 66 ++++++++++++++++ 8 files changed, 350 insertions(+), 53 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml delete mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml create mode 100644 .scripts/linux.sh create mode 100755 .scripts/macOS.sh create mode 100644 .scripts/windows.bat diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 8f5f1d6..0000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -title: '' -labels: bug, triage -assignees: '' - ---- - -**Describe the bug** -A clear and concise description of what the bug is. - -**To Reproduce** -Steps to reproduce the behavior: -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Screenshots** -If applicable, add screenshots to help explain your problem. - -**Environment (please complete the following information):** - - OS and Architecture: [e.g. MacOS, Apple Silicon/aarch64) - - Scope Version [e.g. 0.1.0] - -**Additional context** -Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..f82a4f9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,65 @@ +name: Bug report +description: Create a report to help us improve +title: "[Bug]: " +labels: ["bug", "triage"] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this bug report! + - type: textarea + id: bug-description + attributes: + label: Describe the bug + description: A clear and concise description of what the bug is + validations: + required: true + - type: textarea + id: reproduction + attributes: + label: Steps to reproduce + description: How can we reproduce this issue? + placeholder: | + 1. Go to '...' + 2. Click on '....' + 3. Scroll down to '....' + 4. See error + validations: + required: true + - type: textarea + id: expected + attributes: + label: Expected behavior + description: What did you expect to happen? + validations: + required: true + - type: input + id: os + attributes: + label: Operating System and Architecture + description: What OS and architecture are you using? + placeholder: "e.g. MacOS, Apple Silicon/aarch64" + validations: + required: true + - type: input + id: version + attributes: + label: Scope Version + description: What version of Scope are you running? + placeholder: "e.g. 0.1.0" + validations: + required: true + - type: textarea + id: screenshots + attributes: + label: Screenshots + description: If applicable, add screenshots to help explain your problem + validations: + required: false + - type: textarea + id: additional + attributes: + label: Additional context + description: Add any other context about the problem here + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 8e0ee3c..0000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for Scope -title: '' -labels: enhancement, triage -assignees: '' - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..ced2c23 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,38 @@ +name: Feature request +description: Suggest an idea for Scope +title: "[Feature]: " +labels: ["enhancement", "triage"] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to suggest a feature! + - type: textarea + id: problem + attributes: + label: Is your feature request related to a problem? + description: A clear and concise description of what the problem is + placeholder: "I'm always frustrated when [...]" + validations: + required: true + - type: textarea + id: solution + attributes: + label: Describe the solution you'd like + description: A clear and concise description of what you want to happen + validations: + required: true + - type: textarea + id: alternatives + attributes: + label: Describe alternatives you've considered + description: A clear and concise description of any alternative solutions or features you've considered + validations: + required: false + - type: textarea + id: additional + attributes: + label: Additional context + description: Add any other context or screenshots about the feature request here + validations: + required: false diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fc917be..1ed1388 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,6 +13,7 @@ on: env: CARGO_TERM_COLOR: always + APP_BUNDLE_ID: "com.scopeclient.desktop" jobs: get-version: @@ -175,6 +176,10 @@ jobs: needs: get-version name: Build macOS (Intel) runs-on: macos-latest + env: + APPLE_ID: ${{ secrets.APPLE_ID }} + APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} + KEYCHAIN_PASSWORD: $(openssl rand -base64 32) steps: - uses: actions/checkout@v4 with: @@ -214,7 +219,7 @@ jobs: CFBundleDisplayName Scope CFBundleIdentifier - com.scope.app + ${{ env.APP_BUNDLE_ID }} CFBundleVersion ${{ needs.get-version.outputs.version }} CFBundlePackageType @@ -233,6 +238,25 @@ jobs: EOF + - name: Import Apple Developer Certificate + env: + APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} + APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} + KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} + run: | + echo $APPLE_CERTIFICATE | base64 --decode > certificate.p12 + security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain + security default-keychain -s build.keychain + security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain + security import certificate.p12 -k build.keychain -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" build.keychain + rm certificate.p12 + + - name: Sign App Bundle + run: | + codesign --force --options runtime --sign "Apple Development" Scope.app + codesign --verify --verbose Scope.app + - name: Create DMG run: | hdiutil create -volname "Scope" -srcfolder Scope.app -ov -format UDZO Scope-${{ needs.get-version.outputs.version }}_intel.dmg @@ -247,6 +271,10 @@ jobs: needs: get-version name: Build macOS (Silicon) runs-on: macos-latest + env: + APPLE_ID: ${{ secrets.APPLE_ID }} + APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} + KEYCHAIN_PASSWORD: $(openssl rand -base64 32) steps: - uses: actions/checkout@v4 with: @@ -286,7 +314,7 @@ jobs: CFBundleDisplayName Scope CFBundleIdentifier - com.scope.app + ${{ env.APP_BUNDLE_ID }} CFBundleVersion ${{ needs.get-version.outputs.version }} CFBundlePackageType @@ -305,6 +333,25 @@ jobs: EOF + - name: Import Apple Developer Certificate + env: + APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} + APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} + KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} + run: | + echo $APPLE_CERTIFICATE | base64 --decode > certificate.p12 + security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain + security default-keychain -s build.keychain + security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain + security import certificate.p12 -k build.keychain -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" build.keychain + rm certificate.p12 + + - name: Sign App Bundle + run: | + codesign --force --options runtime --sign "Apple Development" Scope.app + codesign --verify --verbose Scope.app + - name: Create DMG run: | hdiutil create -volname "Scope" -srcfolder Scope.app -ov -format UDZO Scope-${{ needs.get-version.outputs.version }}_silicon.dmg diff --git a/.scripts/linux.sh b/.scripts/linux.sh new file mode 100644 index 0000000..22a0148 --- /dev/null +++ b/.scripts/linux.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +if [ -f .env ]; then + export $(cat .env | grep -v '^#' | xargs) +fi + +set -e + +echo "Building Scope..." +cargo build --release + +echo "Creating AppImage structure..." +mkdir -p AppDir/usr/share/applications +mkdir -p AppDir/usr/share/icons/hicolor/256x256/apps/ +mkdir -p AppDir/usr/bin + +cat > AppDir/usr/share/applications/scope.desktop << EOF +[Desktop Entry] +Name=Scope +Exec=scope +Icon=scope +Type=Application +Categories=Development; +EOF + +echo "Copying files..." +cp target/release/scope AppDir/usr/bin/ +cp .github/scope-round-200.png AppDir/usr/share/icons/hicolor/256x256/apps/scope.png + +echo "Installing AppImage dependencies..." +sudo apt-get update +sudo apt-get install -y libfuse2 + +echo "Creating AppImage..." +wget -O linuxdeploy-x86_64.AppImage https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage +chmod +x linuxdeploy-x86_64.AppImage +./linuxdeploy-x86_64.AppImage --appdir AppDir --output appimage + +VERSION=$(grep '^version = ' src/ui/Cargo.toml | cut -d '"' -f2) +mv Scope*.AppImage ../Scope-${VERSION}.AppImage +rm -rf AppDir linuxdeploy-x86_64.AppImage + +echo "Build complete! AppImage is ready: Scope-${VERSION}.AppImage" diff --git a/.scripts/macOS.sh b/.scripts/macOS.sh new file mode 100755 index 0000000..d57b5e1 --- /dev/null +++ b/.scripts/macOS.sh @@ -0,0 +1,89 @@ +#!/bin/bash + +# APPLE_CERTIFICATE - Your Apple Developer certificate +# APPLE_CERTIFICATE_PASSWORD - Password for your certificate +# APPLE_ID - Your Apple ID email +# APPLE_ID_PASSWORD - Your Apple ID password +# KEYCHAIN_PASSWORD - Password for the keychain +# APP_BUNDLE_ID - Your app bundle identifier (e.g., "com.scope.app") + +if [ -f .env ]; then + export $(cat .env | grep -v '^#' | xargs) +fi + +set -e + +required_vars=("APPLE_CERTIFICATE" "APPLE_CERTIFICATE_PASSWORD" "APPLE_ID" "APPLE_ID_PASSWORD" "KEYCHAIN_PASSWORD" "APP_BUNDLE_ID") +for var in "${required_vars[@]}"; do + if [ -z "${!var}" ]; then + exit 1 + fi +done + +echo "Building Scope..." +cargo build --release + +echo "Creating app bundle..." +mkdir -p Scope.app/Contents/{MacOS,Resources} +cp target/release/scope Scope.app/Contents/MacOS/ +cp .github/scope-round-200.png Scope.app/Contents/Resources/scope.icns + +cat > Scope.app/Contents/Info.plist << EOF + + + + + CFBundleName + Scope + CFBundleDisplayName + Scope + CFBundleIdentifier + ${APP_BUNDLE_ID} + CFBundleVersion + $(grep '^version = ' src/ui/Cargo.toml | cut -d '"' -f2) + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleExecutable + scope + CFBundleIconFile + scope.icns + LSMinimumSystemVersion + 10.13 + NSHighResolutionCapable + + + +EOF + +echo "Setting up certificate..." +rm -f certificate.p12 +echo "$APPLE_CERTIFICATE" | base64 --decode > certificate.p12 2>/dev/null +security import certificate.p12 -P "$APPLE_CERTIFICATE_PASSWORD" -A 2>/dev/null + +SIGNING_IDENTITY=$(security find-identity -v -p codesigning | grep "Apple Development" | head -1 | awk -F '"' '{print $2}') + +if [ -z "$SIGNING_IDENTITY" ]; then + exit 1 +fi + +echo "Using signing identity: $SIGNING_IDENTITY" +echo "Signing application..." +codesign --force --options runtime --sign "$SIGNING_IDENTITY" Scope.app 2>/dev/null + +rm -f certificate.p12 + +echo "Creating DMG..." +hdiutil create -volname "Scope" -srcfolder Scope.app -ov -format UDZO Scope.dmg + +echo "Signing DMG..." +codesign --force --sign "$APPLE_CERTIFICATE" Scope.dmg 2>/dev/null + +echo "Notarizing DMG..." +xcrun notarytool submit Scope.dmg --apple-id "$APPLE_ID" --password "$APPLE_ID_PASSWORD" --team-id "$APPLE_CERTIFICATE" --wait + +echo "Stapling notarization..." +xcrun stapler staple Scope.dmg + +echo "Build complete! Signed and notarized DMG is ready: Scope.dmg" diff --git a/.scripts/windows.bat b/.scripts/windows.bat new file mode 100644 index 0000000..d9ec5b4 --- /dev/null +++ b/.scripts/windows.bat @@ -0,0 +1,66 @@ +@echo off +setlocal enabledelayedexpansion + +if exist .env ( + for /f "tokens=*" %%a in (.env) do set %%a +) + +echo Building Scope... +cargo build --release + +echo Creating installer directory structure... +mkdir installer\bin + +echo Copying files... +copy target\release\scope.exe installer\bin\ +copy .github\scope-round-200.png installer\scope.ico + +echo Creating WiX files... +( +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +) > scope.wxs + +echo Building MSI... +candle scope.wxs +light -ext WixUIExtension scope.wixobj + +echo Cleaning up build files... +rmdir /s /q installer +del scope.wxs +del scope.wixobj +del scope.wixpdb + +echo Build complete! MSI installer is ready: scope.msi From c927b0d31b0bdb1a6a1529f5876345e8fdbe3ca6 Mon Sep 17 00:00:00 2001 From: Christian Bergschneider Date: Mon, 18 Nov 2024 22:17:41 +0100 Subject: [PATCH 08/10] feat: show message timestamp next to the top message that is grouped --- .editorconfig | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f21c5ca --- /dev/null +++ b/.editorconfig @@ -0,0 +1,10 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +insert_final_newline = true +tab_width = 2 +indent_size = 2 +trim_trailing_whitespace = true \ No newline at end of file From 7f89ab7e6b1fe1b838002f1456713eb560bde0d1 Mon Sep 17 00:00:00 2001 From: Alistair Smith Date: Mon, 18 Nov 2024 20:14:17 -0800 Subject: [PATCH 09/10] chore: rm .editorconfig --- .editorconfig | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index f21c5ca..0000000 --- a/.editorconfig +++ /dev/null @@ -1,10 +0,0 @@ -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_style = space -insert_final_newline = true -tab_width = 2 -indent_size = 2 -trim_trailing_whitespace = true \ No newline at end of file From 79d78f691d11a6f0510ce5f31cbc6434f6e23003 Mon Sep 17 00:00:00 2001 From: Alistair Smith Date: Mon, 18 Nov 2024 22:39:06 -0800 Subject: [PATCH 10/10] cleaner --- src/ui/src/main.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/ui/src/main.rs b/src/ui/src/main.rs index e7b9e86..1095cbc 100644 --- a/src/ui/src/main.rs +++ b/src/ui/src/main.rs @@ -36,10 +36,6 @@ fn init(_: Arc, cx: &mut AppContext) -> Result<()> { Ok(()) } -fn quit(_: &actions::Quit, cx: &mut AppContext) { - cx.quit(); -} - #[tokio::main] async fn main() { env_logger::init(); @@ -55,8 +51,9 @@ async fn main() { } cx.bind_keys(vec![KeyBinding::new("cmd-q", actions::Quit, None)]); - cx.on_action(quit); + cx.set_menus(app_menus()); + cx.on_action(|_: &Quit, cx| cx.quit()); let mut theme = Theme::from(ThemeColor::dark()); theme.mode = ThemeMode::Dark;