Update Auto-complete.tsx (#1061)

* chore: fix release workflow to merge docs branch

* fix: svg donation generator push fail

* fix: svg donation generator push fail

* Update termix.rb

* fix: svg donation generator push fail

* chore: move donation badge to badges branch to avoid ruleset conflicts

* chore: remove unneeded token from donation badge workflow

* chore: debug donation badge commit step

* fix: escape < character in donation SVG

* fix: point donation badge to badges branch

* chore: remove unused donation badge svg from main

* Add Rack Genius logo to README

Added Rack Genius logo to the README.

* chore: improve donation goal svg generator to include stablecoins

* chore: donation goal generator syntax error

* chore: donation goal generator incorrect docs url usage

* chore: donation bar reporting wrong result

* feat: add Open File Manager to tab right-click menu (#1046)

* Revert "feat: add Open File Manager to tab right-click menu (#1046)" (#1050)

This reverts commit 0712fdd731.

* Remove donation badge from README

Removed donation badge from README.

* Delete .github/workflows/donation-goal.yml

* Update Auto-complete.tsx

---------

Co-authored-by: LukeGus <bugattiguy527@gmail.com>
Co-authored-by: Luke Gustafson <88517757+LukeGus@users.noreply.github.com>
Co-authored-by: ZacharyZcR <zacharyzcr1984@gmail.com>
This commit is contained in:
Sankeerth Nara
2026-07-16 09:28:33 +05:30
committed by GitHub
parent 71a63ae5e8
commit 0a16adf237
3 changed files with 3 additions and 199 deletions
-181
View File
@@ -1,181 +0,0 @@
name: Donation Goal Badge
on:
schedule:
- cron: "0 */6 * * *"
workflow_dispatch:
jobs:
update:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
ref: badges
- name: Generate donation goal SVG
run: |
set -e
EVM_ADDRESS="0x83eA1Db55cc6E34fCD11Da2b7849621af67b6E34"
BTC_ADDRESS="bc1qrxc3vpnl6qhh9p8akjmjukcgmgmq852ua64h05"
SOL_ADDRESS="T4BF5ioySVUjwaPNw4Sdu7oK8SXLxgQRcMaTQ6YJ2UJ"
DOCS_SNAPSHOT_URL="https://raw.githubusercontent.com/Termix-SSH/Docs/main/static/donation-snapshot.json"
MONTHLY_GOAL=750
# Ethereum mainnet stablecoin contracts
ETH_USDC="0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
ETH_USDT="0xdAC17F958D2ee523a2206206994597C13D831ec7"
ETH_DAI="0x6B175474E89094C44Da98b954EedeAC495271d0F"
# Base stablecoin contracts
BASE_USDC="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
BASE_USDT="0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2"
BASE_DAI="0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb"
# Fetch crypto prices
PRICES=$(curl -sf "https://api.coingecko.com/api/v3/simple/price?ids=ethereum,bitcoin,solana&vs_currencies=usd" || echo '{}')
ETH_PRICE=$(echo "$PRICES" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('ethereum',{}).get('usd',0))" 2>/dev/null || echo 0)
BTC_PRICE=$(echo "$PRICES" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('bitcoin',{}).get('usd',0))" 2>/dev/null || echo 0)
SOL_PRICE=$(echo "$PRICES" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('solana',{}).get('usd',0))" 2>/dev/null || echo 0)
# Fetch live balances
ETH_RAW=$(curl -sf "https://eth.blockscout.com/api/v2/addresses/${EVM_ADDRESS}" || echo '{"coin_balance":"0"}')
ETH_BAL=$(echo "$ETH_RAW" | python3 -c "import sys,json; d=json.load(sys.stdin); print(int(d.get('coin_balance','0')) / 1e18)" 2>/dev/null || echo 0)
BASE_RAW=$(curl -sf "https://base.blockscout.com/api/v2/addresses/${EVM_ADDRESS}" || echo '{"coin_balance":"0"}')
BASE_BAL=$(echo "$BASE_RAW" | python3 -c "import sys,json; d=json.load(sys.stdin); print(int(d.get('coin_balance','0')) / 1e18)" 2>/dev/null || echo 0)
BTC_RAW=$(curl -sf "https://blockstream.info/api/address/${BTC_ADDRESS}" || echo '{"chain_stats":{"funded_txo_sum":0,"spent_txo_sum":0}}')
BTC_BAL=$(echo "$BTC_RAW" | python3 -c "import sys,json; d=json.load(sys.stdin); s=d.get('chain_stats',{}); print((s.get('funded_txo_sum',0)-s.get('spent_txo_sum',0))/1e8)" 2>/dev/null || echo 0)
SOL_RAW=$(curl -sf -X POST "https://api.mainnet-beta.solana.com" \
-H "Content-Type: application/json" \
-d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"getBalance\",\"params\":[\"${SOL_ADDRESS}\"]}" || echo '{"result":{"value":0}}')
SOL_BAL=$(echo "$SOL_RAW" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('result',{}).get('value',0)/1e9)" 2>/dev/null || echo 0)
# Helper: fetch an ERC-20 token balance from Blockscout token-balances endpoint
fetch_token_balance() {
local base_url="$1"
local contract="$2"
curl -sf "${base_url}/api/v2/addresses/${EVM_ADDRESS}/tokens?type=ERC-20" | CONTRACT="$contract" python3 -c "import sys, json, os; contract = os.environ['CONTRACT'].lower(); d = json.load(sys.stdin); match = next((i for i in d.get('items', []) if i.get('token', {}).get('address', '').lower() == contract), None); decimals = int((match or {}).get('token', {}).get('decimals') or 18); value = int((match or {}).get('value') or 0); print(value / (10 ** decimals) if match else 0)" 2>/dev/null || echo 0
}
ETH_USDC_BAL=$(fetch_token_balance "https://eth.blockscout.com" "$ETH_USDC")
ETH_USDT_BAL=$(fetch_token_balance "https://eth.blockscout.com" "$ETH_USDT")
ETH_DAI_BAL=$(fetch_token_balance "https://eth.blockscout.com" "$ETH_DAI")
BASE_USDC_BAL=$(fetch_token_balance "https://base.blockscout.com" "$BASE_USDC")
BASE_USDT_BAL=$(fetch_token_balance "https://base.blockscout.com" "$BASE_USDT")
BASE_DAI_BAL=$(fetch_token_balance "https://base.blockscout.com" "$BASE_DAI")
# Fetch snapshot baseline from docs repo
SNAPSHOT=$(curl -sf "$DOCS_SNAPSHOT_URL" || echo '{"ethBal":0,"baseBal":0,"btcBal":0,"solBal":0}')
SNAP_ETH=$(echo "$SNAPSHOT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('ethBal',0))" 2>/dev/null || echo 0)
SNAP_BASE=$(echo "$SNAPSHOT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('baseBal',0))" 2>/dev/null || echo 0)
SNAP_BTC=$(echo "$SNAPSHOT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('btcBal',0))" 2>/dev/null || echo 0)
SNAP_SOL=$(echo "$SNAPSHOT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('solBal',0))" 2>/dev/null || echo 0)
SNAP_ETH_USDC=$(echo "$SNAPSHOT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('ethUsdcBal',0))" 2>/dev/null || echo 0)
SNAP_ETH_USDT=$(echo "$SNAPSHOT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('ethUsdtBal',0))" 2>/dev/null || echo 0)
SNAP_ETH_DAI=$(echo "$SNAPSHOT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('ethDaiBal',0))" 2>/dev/null || echo 0)
SNAP_BASE_USDC=$(echo "$SNAPSHOT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('baseUsdcBal',0))" 2>/dev/null || echo 0)
SNAP_BASE_USDT=$(echo "$SNAPSHOT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('baseUsdtBal',0))" 2>/dev/null || echo 0)
SNAP_BASE_DAI=$(echo "$SNAPSHOT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('baseDaiBal',0))" 2>/dev/null || echo 0)
export ETH_BAL BASE_BAL BTC_BAL SOL_BAL SNAP_ETH SNAP_BASE SNAP_BTC SNAP_SOL ETH_PRICE BTC_PRICE SOL_PRICE MONTHLY_GOAL
export ETH_USDC_BAL ETH_USDT_BAL ETH_DAI_BAL BASE_USDC_BAL BASE_USDT_BAL BASE_DAI_BAL
export SNAP_ETH_USDC SNAP_ETH_USDT SNAP_ETH_DAI SNAP_BASE_USDC SNAP_BASE_USDT SNAP_BASE_DAI
python3 - <<'PYEOF'
import os, math
eth_bal = float(os.environ.get('ETH_BAL', 0))
base_bal = float(os.environ.get('BASE_BAL', 0))
btc_bal = float(os.environ.get('BTC_BAL', 0))
sol_bal = float(os.environ.get('SOL_BAL', 0))
snap_eth = float(os.environ.get('SNAP_ETH', 0))
snap_base = float(os.environ.get('SNAP_BASE', 0))
snap_btc = float(os.environ.get('SNAP_BTC', 0))
snap_sol = float(os.environ.get('SNAP_SOL', 0))
eth_price = float(os.environ.get('ETH_PRICE', 0))
btc_price = float(os.environ.get('BTC_PRICE', 0))
sol_price = float(os.environ.get('SOL_PRICE', 0))
goal = float(os.environ.get('MONTHLY_GOAL', 750))
eth_usdc_bal = float(os.environ.get('ETH_USDC_BAL', 0))
eth_usdt_bal = float(os.environ.get('ETH_USDT_BAL', 0))
eth_dai_bal = float(os.environ.get('ETH_DAI_BAL', 0))
base_usdc_bal = float(os.environ.get('BASE_USDC_BAL', 0))
base_usdt_bal = float(os.environ.get('BASE_USDT_BAL', 0))
base_dai_bal = float(os.environ.get('BASE_DAI_BAL', 0))
snap_eth_usdc = float(os.environ.get('SNAP_ETH_USDC', 0))
snap_eth_usdt = float(os.environ.get('SNAP_ETH_USDT', 0))
snap_eth_dai = float(os.environ.get('SNAP_ETH_DAI', 0))
snap_base_usdc = float(os.environ.get('SNAP_BASE_USDC', 0))
snap_base_usdt = float(os.environ.get('SNAP_BASE_USDT', 0))
snap_base_dai = float(os.environ.get('SNAP_BASE_DAI', 0))
delta_eth = max(0, eth_bal - snap_eth)
delta_base = max(0, base_bal - snap_base)
delta_btc = max(0, btc_bal - snap_btc)
delta_sol = max(0, sol_bal - snap_sol)
delta_eth_usdc = max(0, eth_usdc_bal - snap_eth_usdc)
delta_eth_usdt = max(0, eth_usdt_bal - snap_eth_usdt)
delta_eth_dai = max(0, eth_dai_bal - snap_eth_dai)
delta_base_usdc = max(0, base_usdc_bal - snap_base_usdc)
delta_base_usdt = max(0, base_usdt_bal - snap_base_usdt)
delta_base_dai = max(0, base_dai_bal - snap_base_dai)
total = (
delta_eth * eth_price + delta_base * eth_price +
delta_btc * btc_price + delta_sol * sol_price +
delta_eth_usdc + delta_eth_usdt + delta_eth_dai +
delta_base_usdc + delta_base_usdt + delta_base_dai
)
pct = min(total / goal * 100, 100) if goal > 0 else 0
if total < 1:
display = '&lt; $1'
else:
display = f'${math.floor(total):,}'
goal_display = f'${int(goal):,}'
W = 400
BAR_W = 360
BAR_X = 20
BAR_H = 8
FILL_W = round(BAR_W * pct / 100)
label = f'Monthly Donation Goal {display} / {goal_display}'
pct_label = f'{round(pct)}% of monthly goal' if pct < 100 else 'Goal reached this month. Thank you!'
svg = f'''<svg xmlns="http://www.w3.org/2000/svg" width="{W}" height="52" role="img" aria-label="Monthly donation goal">
<title>Monthly donation goal</title>
<rect width="{W}" height="52" rx="6" fill="#0c0d0b"/>
<text x="{W//2}" y="13" font-family="sans-serif" font-size="11" fill="#F39044" text-anchor="middle">{label}</text>
<rect x="{BAR_X}" y="20" width="{BAR_W}" height="{BAR_H}" rx="4" fill="#F3904433"/>
<rect x="{BAR_X}" y="20" width="{FILL_W}" height="{BAR_H}" rx="4" fill="#F39044"/>
<text x="{W//2}" y="44" font-family="sans-serif" font-size="10" fill="#F3904499" text-anchor="middle">{pct_label}</text>
</svg>'''
with open('donation-goal.svg', 'w') as f:
f.write(svg)
print(f'SVG written: {display} / {goal_display} ({round(pct)}%)')
PYEOF
- name: Commit SVG
run: |
git config user.name "LukeGus"
git config user.email "bugattiguy527@gmail.com"
git add -f donation-goal.svg
git diff --cached --stat
if git diff --cached --quiet; then
echo "No changes to commit"
exit 0
fi
git commit -m "chore: update donation goal badge"
git push origin HEAD:badges
+1 -16
View File
@@ -35,7 +35,7 @@
Termix is free and open source. If you find it useful, consider [donating](https://donate.termix.site/) to help cover server costs and development time. Termix is free and open source. If you find it useful, consider [donating](https://donate.termix.site/) to help cover server costs and development time.
<a href="https://donate.termix.site/"><img src="https://raw.githubusercontent.com/Termix-SSH/Termix/badges/donation-goal.svg" alt="Monthly donation goal" /></a> <a href="https://donate.termix.site/"><img src="./repo-images/donation-goal.svg" alt="Monthly donation goal" /></a>
<br /> <br />
@@ -266,8 +266,6 @@ services:
- termix-data:/app/data - termix-data:/app/data
environment: environment:
PORT: "8080" PORT: "8080"
GUACD_HOST: "guacd"
GUACD_RECORDING_PATH: "/termix-data/session_recordings/guacamole"
depends_on: depends_on:
- guacd - guacd
networks: networks:
@@ -279,8 +277,6 @@ services:
restart: unless-stopped restart: unless-stopped
ports: ports:
- "4822:4822" - "4822:4822"
volumes:
- termix-data:/termix-data
networks: networks:
- termix-net - termix-net
@@ -293,13 +289,6 @@ networks:
driver: bridge driver: bridge
``` ```
Termix records enabled SSH, RDP, VNC, and Telnet sessions for replay and audit.
When using an external `guacd`, mount the same recording storage into both
services and set `GUACD_RECORDING_PATH` to the path visible to `guacd` and
`GUACD_RECORDING_BACKEND_PATH` to the corresponding path visible to Termix.
Administrators can change the default 30-day retention period from Session Logs
or with `SESSION_RECORDING_RETENTION_DAYS`.
<br /> <br />
## Donate ## Donate
@@ -403,10 +392,6 @@ See [Projects](https://github.com/orgs/Termix-SSH/projects/5) for all planned fe
<a href="https://aws.amazon.com/"> <a href="https://aws.amazon.com/">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Amazon_Web_Services_Logo.svg/960px-Amazon_Web_Services_Logo.svg.png" height="40" alt="AWS" /> <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Amazon_Web_Services_Logo.svg/960px-Amazon_Web_Services_Logo.svg.png" height="40" alt="AWS" />
</a> </a>
&nbsp;&nbsp;&nbsp;
<a href="https://rackgenius.com/">
<img src="https://rackgenius.com/rackgenius-logo.png" height="40" alt="AWS" />
</a>
</div> </div>
@@ -54,9 +54,9 @@ export function CommandAutocomplete({
key={index} key={index}
ref={index === selectedIndex ? selectedRef : null} ref={index === selectedIndex ? selectedRef : null}
className={cn( className={cn(
"px-3 py-1.5 text-sm font-mono cursor-pointer transition-colors", "px-3 py-1.5 text-sm font-mono cursor-pointer transition-colors text-foreground",
"hover:bg-hover", "hover:bg-hover",
index === selectedIndex && "bg-surface text-muted-foreground", index === selectedIndex && "bg-accent text-accent-foreground",
)} )}
onClick={() => onSelect(suggestion)} onClick={() => onSelect(suggestion)}
onMouseEnter={() => {}} onMouseEnter={() => {}}