OXYGENHUB

Overview: the clone control looks like a button, and unsigned changes with no author count as unattributed 6ad368c5958e

refs #18
Author
Andy McCall @andymccall <[email protected]>
When
· 2026-09-28 15:56 UTC
Signature
✔ signed by Andy McCall
Hash
6ad368c5958ea7cca4655ddb3edbe0d4d00a53a3f469b861d1c1a83c33564335
Depends on
5c6eb1feaa71 83d5052bf76c d23464c0ac60
Depended on by
c9aacc0e7dc1 8933faff2043 67b24adbf35a df940d75cd3d
In bookmarks
api-unknown-fields cancel-landed-runs clear-waiting close-proposal-140 diffusion-pin-bookmark draft-ready image-check job-waits main oh-comment-body-file proposal-list-fast run-one-job wiki-says-so
In tags
v0.1.0 v0.2.0 v0.3.0 v0.3.1 v0.4.0 v0.4.1 v0.4.2 v0.5.0 v0.5.1 v0.5.2 v0.6.0 v0.6.1 v0.7.0 v0.8.0 v0.9.0 v0.9.1 v0.9.11 v0.9.15 v0.9.16 v0.9.19 v0.9.2 v0.9.20 v0.9.21 v0.9.22 v0.9.23 v0.9.24 v0.9.3 v0.9.4 v0.9.5 v0.9.6 v0.9.7 v0.9.8 v0.9.9
Edits
7 atoms, 0 tree operations, 3 files

Browse the tree at this change

modified crates/hub/src/repos/view.rs +4 −1
…
764 unchanged lines
765 765
    for (_, meta) in state.changes() {
766 766
        let a = author(repo, &meta.author, &meta.message);
767 767
        let id = if a.key.is_empty() { format!("git:{}", a.email.to_lowercase()) } else { a.key.clone() };
768 -
        by.entry(id).or_insert_with(|| Contributor { name: a.name.clone(), key: a.key.clone(), changes: 0, account: None }).changes += 1;
768 +
        // Unsigned changes with no Git author carry no name at all.
769 +
        let name =
770 +
            if a.key.is_empty() && a.email.is_empty() && a.name == "unknown" { "Unattributed changes".to_string() } else { a.name.clone() };
771 +
        by.entry(id).or_insert_with(|| Contributor { name, key: a.key.clone(), changes: 0, account: None }).changes += 1;
769 772
    }
770 773
    let mut out: Vec<Contributor> = by.into_values().collect();
771 774
    out.sort_by(|a, b| b.changes.cmp(&a.changes).then(a.name.cmp(&b.name)));
…
528 unchanged lines
modified templates/overview.html +1 −1
…
13 unchanged lines
14 14
      {% if repo.can(crate::auth::Access::Write) %}<a class="go small" href="{{ repo.url }}/newfile/{{ repo.default_bookmark }}">new file</a>{% endif %}
15 15
      <form class="find inline-find" method="get" action="{{ repo.url }}/search"><input type="search" name="q" placeholder="Search code…"></form>
16 16
      <details class="clone-pop">
17 -
        <summary class="go small">⤓ clone</summary>
17 +
        <summary class="go small" aria-haspopup="true">⤓ Clone</summary>
18 18
        <div class="clone-panel" role="group" aria-label="Clone this repository">
19 19
          <label for="clone-cmd" class="small mute">Clone with oxy</label>
20 20
          <div class="clone"><input id="clone-cmd" type="text" readonly value="oxy clone {{ repo.clone_url }}" onfocus="this.select()" onclick="this.select()"><button type="button" class="small" data-copy="oxy clone {{ repo.clone_url }}">copy</button></div>
…
54 unchanged lines
modified templates/style.css +3 −1
…
98 unchanged lines
99 99
.sheet td { padding: 2px 8px 2px 0; font-size: 13px; }
100 100
101 101
/* buttons, tags, chips */
102 -
button, a.go, button.go { font: inherit; font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .08em; background: var(--panel); color: var(--acc); border: 1px solid var(--acc); padding: 5px 10px; cursor: pointer; }
102 +
button, a.go, button.go, summary.go { font: inherit; font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .08em; background: var(--panel); color: var(--acc); border: 1px solid var(--acc); padding: 5px 10px; cursor: pointer; }
103 103
button:hover, a.go:hover { background: var(--acc); color: var(--now-ink); text-decoration: none; }
104 104
button.small, a.go.small { padding: 2px 8px; font-size: 11px; }
105 105
.tag { display: inline-block; font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--acc); background: var(--soft); padding: 1px 6px; vertical-align: middle; }
…
435 unchanged lines
541 541
.vis-public { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 45%, transparent); }
542 542
.vis-internal { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 45%, transparent); }
543 543
.vis-private { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 45%, transparent); }
544 +
summary.go { display: inline-block; user-select: none; }
545 +
.clone-pop > summary.go:hover { background: var(--soft); }