feat(gpui): add the Fluxion AI sponsor page and Discord link
Settings → Home → Project and support gains a Sponsors row that opens an in-app page (logo on the left, bilingual introduction on the right) with a single sign-up link carrying the project's attribution parameters. Both READMEs add a matching Sponsors table and the community Discord invite.
This commit is contained in:
1 parent
41c5477c57
commit
ffec205e01
7 files changed
+205
-3
No files matched your search
@@ -27,6 +27,7 @@
|
||||
<img src="https://img.shields.io/github/stars/Kuddev/pebrel?style=flat-square&color=ffd33d&logo=github" alt="Stars" />
|
||||
<img src="https://img.shields.io/github/forks/Kuddev/pebrel?style=flat-square&color=8957e5&logo=github" alt="Forks" />
|
||||
<img src="https://img.shields.io/github/last-commit/Kuddev/pebrel?style=flat-square&color=3fb950" alt="Last commit" />
|
||||
<a href="https://discord.gg/VFn4rcxmhn"><img src="https://img.shields.io/badge/Discord-join-5865F2?style=flat-square&logo=discord&logoColor=white" alt="Discord" /></a>
|
||||
<a href="https://linux.do"><img src="https://img.shields.io/badge/%E5%8F%8B%E9%93%BE-linux.do-ffb003?style=flat-square&logo=discourse&logoColor=white" alt="linux.do" /></a>
|
||||
</p>
|
||||
|
||||
@@ -48,6 +49,20 @@
|
||||
<img src="docs/screenshots/split-ai-workflows.png" alt="OpenCode, Claude Code, and Codex in split panes" width="1040" />
|
||||
</p>
|
||||
|
||||
## 💖 Sponsors
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center" width="240">
|
||||
<a href="https://fluxionai.space/register?source=github&campaign=pebrel&promo=pebrel"><img src="extra/logo/sponsor_fluxionai.png" alt="Fluxion AI" width="200" /></a><br />
|
||||
<a href="https://fluxionai.space/register?source=github&campaign=pebrel&promo=pebrel"><strong>Fluxion AI</strong></a>
|
||||
</td>
|
||||
<td>
|
||||
Thanks to Fluxion AI for sponsoring this project! Fluxion AI is one entry point for accessing and managing the world's leading AI models. It serves individual developers, technical teams and enterprises with a unified API; dynamic multi-route scheduling improves availability, and model performance, response time and cost stay transparent. Depending on the model and route, API calls can cost 40%–98% less than official or benchmark prices. <a href="https://fluxionai.space/register?source=github&campaign=pebrel&promo=pebrel">Sign up via this link</a> to receive $3 in API credit.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## One Workspace
|
||||
|
||||
Pebrel (formerly Nebula) brings local shells, remote hosts, files, and AI command-line
|
||||
@@ -176,6 +191,8 @@ through the explicit `legacy-shell` feature.
|
||||
|
||||
Email: [fickleheartedkeys@163.com](mailto:fickleheartedkeys@163.com)
|
||||
|
||||
Discord: [discord.gg/VFn4rcxmhn](https://discord.gg/VFn4rcxmhn)
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
Pebrel builds on [Alacritty](https://github.com/alacritty/alacritty),
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
<img src="https://img.shields.io/github/stars/Kuddev/pebrel?style=flat-square&color=ffd33d&logo=github" alt="Stars" />
|
||||
<img src="https://img.shields.io/github/forks/Kuddev/pebrel?style=flat-square&color=8957e5&logo=github" alt="Forks" />
|
||||
<img src="https://img.shields.io/github/last-commit/Kuddev/pebrel?style=flat-square&color=3fb950" alt="最近提交" />
|
||||
<a href="https://discord.gg/VFn4rcxmhn"><img src="https://img.shields.io/badge/Discord-join-5865F2?style=flat-square&logo=discord&logoColor=white" alt="Discord" /></a>
|
||||
<a href="https://linux.do"><img src="https://img.shields.io/badge/%E5%8F%8B%E9%93%BE-linux.do-ffb003?style=flat-square&logo=discourse&logoColor=white" alt="linux.do" /></a>
|
||||
</p>
|
||||
|
||||
@@ -48,6 +49,20 @@
|
||||
<img src="docs/screenshots/split-ai-workflows.png" alt="OpenCode、Claude Code 与 Codex 分屏工作流" width="1040" />
|
||||
</p>
|
||||
|
||||
## 💖 赞助商
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center" width="240">
|
||||
<a href="https://fluxionai.space/register?source=github&campaign=pebrel&promo=pebrel"><img src="extra/logo/sponsor_fluxionai.png" alt="Fluxion AI" width="200" /></a><br />
|
||||
<a href="https://fluxionai.space/register?source=github&campaign=pebrel&promo=pebrel"><strong>Fluxion AI</strong></a>
|
||||
</td>
|
||||
<td>
|
||||
感谢 Fluxion AI 赞助本项目!Fluxion AI 是一个入口,接入并管理全球主流 AI 模型:面向个人开发者、技术团队与企业,通过统一 API 接入并管理全球主流 AI 模型;通过多线路动态调度提升可用性,模型表现、响应时间与费用透明可查。根据不同模型与线路,API 调用成本较官方或基准价格可降低 40%—98%。<a href="https://fluxionai.space/register?source=github&campaign=pebrel&promo=pebrel">立即访问并注册</a>,即可获得 $3 API 额度。
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## 一个工作区
|
||||
|
||||
Pebrel(原名 Nebula)把本地 Shell、远程主机、文件和 AI 命令行工具放进同一个原生桌面工作区。
|
||||
@@ -158,6 +173,8 @@ cargo build --release --locked -p nebula --bin pebrel --features gpui-shell
|
||||
|
||||
邮箱:[fickleheartedkeys@163.com](mailto:fickleheartedkeys@163.com)
|
||||
|
||||
Discord:[discord.gg/VFn4rcxmhn](https://discord.gg/VFn4rcxmhn)
|
||||
|
||||
## 致谢
|
||||
|
||||
Pebrel 基于 [Alacritty](https://github.com/alacritty/alacritty)、
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
@@ -63,6 +63,7 @@ mod notifications;
|
||||
mod shell_picker;
|
||||
#[cfg(all(test, feature = "gpui-test-support"))]
|
||||
mod shell_picker_tests;
|
||||
mod sponsor;
|
||||
mod status;
|
||||
mod theme_advanced;
|
||||
mod theme_editor;
|
||||
@@ -115,6 +116,8 @@ pub struct SettingsPane {
|
||||
about_update: AboutUpdateState,
|
||||
about_update_seq: u64,
|
||||
about_last_checked: Option<String>,
|
||||
/// 首页「项目与支持」→ 赞助商:独立页面,不是外链行。切换分区时清掉。
|
||||
about_sponsor_open: bool,
|
||||
settings_search_input: Entity<InputState>,
|
||||
search_origin_section: Option<usize>,
|
||||
/// 每项还带着自己的 `values` 表:`SelectState` 只认索引,而从代码侧
|
||||
@@ -1295,6 +1298,7 @@ impl SettingsPane {
|
||||
.into_any_element();
|
||||
}
|
||||
match self.active_section {
|
||||
0 if self.about_sponsor_open => self.section_sponsor(cx),
|
||||
0 => self.section_home(window, cx),
|
||||
1 => self.section_appearance(window, cx),
|
||||
2 => self.section_profiles(window, cx),
|
||||
@@ -1379,6 +1383,7 @@ impl SettingsPane {
|
||||
.when(!active, |item| item.text_color(muted).hover(|s| s.bg(hover_bg)))
|
||||
.on_click(cx.listener(move |this, _, _, cx| {
|
||||
this.active_section = ix;
|
||||
this.about_sponsor_open = false;
|
||||
cx.notify();
|
||||
}))
|
||||
.child(
|
||||
|
||||
@@ -8,6 +8,31 @@ impl SettingsPane {
|
||||
url: String,
|
||||
cx: &Context<Self>,
|
||||
) -> gpui::AnyElement {
|
||||
Self::about_row(id, icon, title, IconName::ExternalLink, cx)
|
||||
.on_click(move |_, _, cx| cx.open_url(&url))
|
||||
.into_any_element()
|
||||
}
|
||||
|
||||
/// 与外链行同一条骨架,尾标是「进入页面」而不是「离开应用」。
|
||||
pub(super) fn about_page_row(
|
||||
id: &'static str,
|
||||
icon: IconName,
|
||||
title: &'static str,
|
||||
on_click: impl Fn(&gpui::ClickEvent, &mut Window, &mut App) + 'static,
|
||||
cx: &Context<Self>,
|
||||
) -> gpui::AnyElement {
|
||||
Self::about_row(id, icon, title, IconName::ChevronRight, cx)
|
||||
.on_click(on_click)
|
||||
.into_any_element()
|
||||
}
|
||||
|
||||
fn about_row(
|
||||
id: &'static str,
|
||||
icon: IconName,
|
||||
title: &'static str,
|
||||
trailing: IconName,
|
||||
cx: &Context<Self>,
|
||||
) -> gpui::Stateful<gpui::Div> {
|
||||
let muted = cx.theme().muted_foreground;
|
||||
let hover = cx.theme().list_hover;
|
||||
h_flex()
|
||||
@@ -21,11 +46,9 @@ impl SettingsPane {
|
||||
.rounded_md()
|
||||
.cursor_pointer()
|
||||
.hover(move |row| row.bg(hover))
|
||||
.on_click(move |_, _, cx| cx.open_url(&url))
|
||||
.child(Icon::new(icon).small().text_color(muted))
|
||||
.child(div().flex_1().min_w_0().child(title))
|
||||
.child(Icon::new(IconName::ExternalLink).xsmall().text_color(muted))
|
||||
.into_any_element()
|
||||
.child(Icon::new(trailing).xsmall().text_color(muted))
|
||||
}
|
||||
|
||||
pub(super) fn about_value_row(
|
||||
@@ -252,6 +275,13 @@ impl SettingsPane {
|
||||
language.pick("更新内容", "Release notes"),
|
||||
crate::update_check::RELEASES_PAGE.to_owned(),
|
||||
cx,
|
||||
))
|
||||
.child(Self::about_page_row(
|
||||
"about-sponsors",
|
||||
IconName::Heart,
|
||||
language.pick("赞助商", "Sponsors"),
|
||||
cx.listener(|this, _, _, cx| this.open_sponsor_page(cx)),
|
||||
cx,
|
||||
));
|
||||
|
||||
v_flex().w_full().child(identity).child(
|
||||
|
||||
@@ -584,6 +584,7 @@ impl SettingsPane {
|
||||
about_update: AboutUpdateState::Idle,
|
||||
about_update_seq: 0,
|
||||
about_last_checked: None,
|
||||
about_sponsor_open: false,
|
||||
settings_search_input,
|
||||
search_origin_section: None,
|
||||
selects,
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
//! 设置首页「项目与支持」下的赞助商页:左侧品牌贴图、右侧介绍与注册链接。
|
||||
//!
|
||||
//! 不做成外链行:外链行一点就跳浏览器,赞助商介绍在应用里就该读得到;
|
||||
//! 页面只提供一条明确的注册链接,点它才离开应用。
|
||||
|
||||
use std::sync::{Arc, OnceLock};
|
||||
|
||||
use super::*;
|
||||
|
||||
/// 注册链接。`source` / `campaign` / `promo` 三个参数是赞助商给本项目的
|
||||
/// 专属归因,README 与应用内必须用同一条,不能各写各的。
|
||||
pub(super) const SPONSOR_URL: &str =
|
||||
"https://fluxionai.space/register?source=github&campaign=pebrel&promo=pebrel";
|
||||
const SPONSOR_NAME: &str = "Fluxion AI";
|
||||
const LOGO_PNG: &[u8] = include_bytes!("../../../../extra/logo/sponsor_fluxionai.png");
|
||||
/// 贴图自带白底圆角,深浅主题都读得清品牌字。
|
||||
const LOGO_WIDTH: f32 = 188.0;
|
||||
|
||||
/// 贴图只解码一次:RGBA8 → BGRA(gpui 帧通道序),与壁纸 / 文档图同款。
|
||||
fn sponsor_logo() -> Option<Arc<RenderImage>> {
|
||||
static LOGO: OnceLock<Option<Arc<RenderImage>>> = OnceLock::new();
|
||||
LOGO.get_or_init(|| {
|
||||
let mut rgba = image::load_from_memory(LOGO_PNG).ok()?.into_rgba8();
|
||||
for pixel in rgba.chunks_exact_mut(4) {
|
||||
pixel.swap(0, 2);
|
||||
}
|
||||
Some(Arc::new(RenderImage::new([image::Frame::new(rgba)])))
|
||||
})
|
||||
.clone()
|
||||
}
|
||||
|
||||
impl SettingsPane {
|
||||
pub(super) fn open_sponsor_page(&mut self, cx: &mut Context<Self>) {
|
||||
self.about_sponsor_open = true;
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub(super) fn close_sponsor_page(&mut self, cx: &mut Context<Self>) {
|
||||
self.about_sponsor_open = false;
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub(super) fn section_sponsor(&mut self, cx: &mut Context<Self>) -> gpui::Div {
|
||||
let language = crate::gpui_shell::config::ui_language(cx);
|
||||
let theme = cx.theme();
|
||||
let muted = theme.muted_foreground;
|
||||
let ink = theme.foreground;
|
||||
let link = theme.primary;
|
||||
let hover = theme.list_hover;
|
||||
let base_px = self.font_size_px(cx);
|
||||
|
||||
let back = h_flex()
|
||||
.id("sponsor-back")
|
||||
.w_auto()
|
||||
.h(px(32.0))
|
||||
.px_2()
|
||||
.gap_2()
|
||||
.items_center()
|
||||
.rounded_md()
|
||||
.cursor_pointer()
|
||||
.text_color(muted)
|
||||
.hover(move |row| row.bg(hover).text_color(ink))
|
||||
.on_click(cx.listener(|this, _, _, cx| this.close_sponsor_page(cx)))
|
||||
.child(Icon::new(IconName::ArrowLeft).small())
|
||||
.child(language.pick("返回", "Back"));
|
||||
|
||||
let logo =
|
||||
div().w(px(LOGO_WIDTH)).flex_shrink_0().when_some(sponsor_logo(), |slot, image| {
|
||||
slot.child(gpui::StyledImage::object_fit(
|
||||
img(image).w(px(LOGO_WIDTH)).h(px(LOGO_WIDTH * 276.0 / 376.0)),
|
||||
gpui::ObjectFit::Contain,
|
||||
))
|
||||
});
|
||||
|
||||
let register = h_flex()
|
||||
.id("sponsor-register")
|
||||
.w_auto()
|
||||
.mt(px(4.0))
|
||||
.gap_1()
|
||||
.items_center()
|
||||
.cursor_pointer()
|
||||
.text_color(link)
|
||||
.hover(|row| row.underline())
|
||||
.on_click(|_, _, cx| cx.open_url(SPONSOR_URL))
|
||||
.child(language.pick(
|
||||
"立即访问并注册,即可获得 $3 API 额度",
|
||||
"Sign up now to receive $3 in API credit",
|
||||
))
|
||||
.child(Icon::new(IconName::ExternalLink).xsmall());
|
||||
|
||||
let copy = v_flex()
|
||||
.flex_1()
|
||||
.min_w_0()
|
||||
.gap(px(10.0))
|
||||
.child(
|
||||
div()
|
||||
.text_size(px(base_px * 1.3))
|
||||
.font_weight(gpui::FontWeight::SEMIBOLD)
|
||||
.text_color(ink)
|
||||
.child(SPONSOR_NAME),
|
||||
)
|
||||
.child(div().text_color(ink).child(language.pick(
|
||||
"一个入口,接入并管理全球主流 AI 模型",
|
||||
"One entry point to access and manage the world's leading AI models",
|
||||
)))
|
||||
.child(div().text_color(muted).line_height(px(base_px * 1.6)).child(language.pick(
|
||||
"Fluxion AI 面向个人开发者、技术团队与企业,通过统一 API 接入并管理全球主流 AI 模型;\
|
||||
通过多线路动态调度提升可用性,模型表现、响应时间与费用透明可查。\
|
||||
根据不同模型与线路,API 调用成本较官方或基准价格可降低 40%—98%。",
|
||||
"Fluxion AI serves individual developers, technical teams and enterprises with a \
|
||||
unified API for accessing and managing mainstream AI models worldwide. Dynamic \
|
||||
multi-route scheduling improves availability, and model performance, response \
|
||||
time and cost stay transparent. Depending on the model and route, API calls can \
|
||||
cost 40%–98% less than official or benchmark prices.",
|
||||
)))
|
||||
.child(register);
|
||||
|
||||
v_flex()
|
||||
.w_full()
|
||||
.gap(px(20.0))
|
||||
.child(back)
|
||||
.child(
|
||||
div()
|
||||
.h(px(30.0))
|
||||
.text_size(px(base_px * 0.85))
|
||||
.font_weight(gpui::FontWeight::SEMIBOLD)
|
||||
.text_color(muted)
|
||||
.child(language.pick("赞助商", "Sponsors")),
|
||||
)
|
||||
.child(h_flex().w_full().items_start().gap(px(28.0)).child(logo).child(copy))
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user