Skip to content

Commit

Permalink
Make homepage more interesting (ordinals#2374)
Browse files Browse the repository at this point in the history
  • Loading branch information
raphjaph authored Aug 27, 2023
1 parent 898c2cd commit 9eb09aa
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 104 deletions.
14 changes: 0 additions & 14 deletions src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -876,20 +876,6 @@ impl Index {
Ok(result)
}

pub(crate) fn get_homepage_inscriptions(&self) -> Result<Vec<InscriptionId>> {
Ok(
self
.database
.begin_read()?
.open_table(INSCRIPTION_NUMBER_TO_INSCRIPTION_ID)?
.iter()?
.rev()
.take(8)
.flat_map(|result| result.map(|(_number, id)| Entry::load(*id.value())))
.collect(),
)
}

pub(crate) fn get_latest_inscriptions_with_prev_and_next(
&self,
n: usize,
Expand Down
25 changes: 25 additions & 0 deletions src/index/block_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,4 +203,29 @@ impl BlockIndex {

Ok(inscriptions)
}

pub(crate) fn get_highest_paying_inscriptions_in_block(
&self,
index: &Index,
block_height: u64,
n: usize,
) -> Result<Vec<InscriptionId>> {
let inscription_ids = self.get_inscriptions_in_block(index, block_height)?;

let mut inscription_to_fee: Vec<(InscriptionId, u64)> = Vec::new();
for id in inscription_ids {
inscription_to_fee.push((id, index.get_inscription_entry(id)?.unwrap().fee));
}

inscription_to_fee.sort_by_key(|(_, fee)| *fee);

Ok(
inscription_to_fee
.iter()
.map(|(id, _)| *id)
.rev()
.take(n)
.collect(),
)
}
}
45 changes: 30 additions & 15 deletions src/subcommand/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -560,15 +560,24 @@ impl Server {
async fn home(
Extension(page_config): Extension<Arc<PageConfig>>,
Extension(index): Extension<Arc<Index>>,
Extension(block_index_state): Extension<Arc<BlockIndexState>>,
) -> ServerResult<PageHtml<HomeHtml>> {
Ok(
HomeHtml::new(index.blocks(100)?, index.get_homepage_inscriptions()?)
.page(page_config, index.has_sat_index()?),
)
let blocks = index.blocks(100)?;
let mut featured_blocks = BTreeMap::new();
for (height, hash) in blocks.iter().take(5) {
let inscriptions = block_index_state
.block_index
.read()
.unwrap()
.get_highest_paying_inscriptions_in_block(&index, *height, 8)?;
featured_blocks.insert(*hash, inscriptions);
}

Ok(HomeHtml::new(blocks, featured_blocks).page(page_config, index.has_sat_index()?))
}

async fn install_script() -> Redirect {
Redirect::to("https://raw.githubusercontent.com/casey/ord/master/install.sh")
Redirect::to("https://raw.githubusercontent.com/ordinals/ord/master/install.sh")
}

async fn block(
Expand Down Expand Up @@ -1545,7 +1554,7 @@ mod tests {
fn install_sh_redirects_to_github() {
TestServer::new().assert_redirect(
"/install.sh",
"https://raw.githubusercontent.com/casey/ord/master/install.sh",
"https://raw.githubusercontent.com/ordinals/ord/master/install.sh",
);
}

Expand Down Expand Up @@ -1960,15 +1969,21 @@ mod tests {
test_server.mine_blocks(1);

test_server.assert_response_regex(
"/",
StatusCode::OK,
".*<title>Ordinals</title>.*
<h2>Latest Blocks</h2>
<ol start=1 reversed class=blocks>
<li><a href=/block/[[:xdigit:]]{64}>[[:xdigit:]]{64}</a></li>
<li><a href=/block/000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f>000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f</a></li>
"/",
StatusCode::OK,
".*<title>Ordinals</title>.*
<div class=block>
<h2><a href=/block/1>Block 1</a></h2>
<div class=thumbnails>
</div>
</div>
<div class=block>
<h2><a href=/block/0>Block 0</a></h2>
<div class=thumbnails>
</div>
</div>
</ol>.*",
);
);
}

#[test]
Expand All @@ -1989,7 +2004,7 @@ mod tests {
test_server.assert_response_regex(
"/",
StatusCode::OK,
".*<ol start=101 reversed class=blocks>\n( <li><a href=/block/[[:xdigit:]]{64}>[[:xdigit:]]{64}</a></li>\n){100}</ol>.*"
".*<ol start=96 reversed class=block-list>\n( <li><a href=/block/[[:xdigit:]]{64}>[[:xdigit:]]{64}</a></li>\n){95}</ol>.*"
);
}

Expand Down
53 changes: 36 additions & 17 deletions src/templates/home.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,22 @@ use super::*;
pub(crate) struct HomeHtml {
last: u64,
blocks: Vec<BlockHash>,
inscriptions: Vec<InscriptionId>,
featured_blocks: BTreeMap<BlockHash, Vec<InscriptionId>>,
}

impl HomeHtml {
pub(crate) fn new(blocks: Vec<(u64, BlockHash)>, inscriptions: Vec<InscriptionId>) -> Self {
pub(crate) fn new(
blocks: Vec<(u64, BlockHash)>,
featured_blocks: BTreeMap<BlockHash, Vec<InscriptionId>>,
) -> Self {
Self {
last: blocks
.get(0)
.map(|(height, _)| height)
.cloned()
.unwrap_or(0),
blocks: blocks.into_iter().map(|(_, hash)| hash).collect(),
inscriptions,
featured_blocks,
}
}
}
Expand All @@ -33,9 +36,23 @@ mod tests {

#[test]
fn html() {
let mut feature_blocks = BTreeMap::new();
feature_blocks.insert(
"2222222222222222222222222222222222222222222222222222222222222222"
.parse()
.unwrap(),
vec![inscription_id(1), inscription_id(2)],
);

assert_regex_match!(
&HomeHtml::new(
vec![
(
1260002,
"2222222222222222222222222222222222222222222222222222222222222222"
.parse()
.unwrap()
),
(
1260001,
"1111111111111111111111111111111111111111111111111111111111111111"
Expand All @@ -49,21 +66,23 @@ mod tests {
.unwrap()
)
],
vec![inscription_id(1), inscription_id(2)],
feature_blocks,
)
.to_string(),
"<h2>Latest Inscriptions</h2>
<div class=thumbnails>
<a href=/inscription/1{64}i1><iframe .* src=/preview/1{64}i1></iframe></a>
<a href=/inscription/2{64}i2><iframe .* src=/preview/2{64}i2></iframe></a>
</div>
<div class=center><a href=/inscriptions>more</a></div>
<h2>Latest Blocks</h2>
<ol start=1260001 reversed class=blocks>
<li><a href=/block/1{64}>1{64}</a></li>
<li><a href=/block/0{64}>0{64}</a></li>
</ol>
",
.to_string()
.unindent(),
"<div class=block>
<h2><a href=/block/1260002>Block 1260002</a></h2>
<div class=thumbnails>
<a href=/inscription/1{64}i1><iframe .* src=/preview/1{64}i1></iframe></a>
<a href=/inscription/2{64}i2><iframe .* src=/preview/2{64}i2></iframe></a>
</div>
</div>
<ol start=1260001 reversed class=block-list>
<li><a href=/block/1{64}>1{64}</a></li>
<li><a href=/block/0{64}>0{64}</a></li>
</ol>
"
.unindent(),
);
}
}
4 changes: 2 additions & 2 deletions src/templates/inscriptions_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ mod tests {
next_page: None,
},
"
<h1>Inscriptions in <a href=/block/21>Block 21</a></h1>
<h1 class=light-fg>Inscriptions in <a href=/block/21>Block 21</a></h1>
<div class=thumbnails>
<a href=/inscription/1{64}i1><iframe .* src=/preview/1{64}i1></iframe></a>
<a href=/inscription/2{64}i2><iframe .* src=/preview/2{64}i2></iframe></a>
Expand All @@ -93,7 +93,7 @@ mod tests {
prev_page: Some(1),
},
"
<h1>Inscriptions in <a href=/block/21>Block 21</a></h1>
<h1 class=light-fg>Inscriptions in <a href=/block/21>Block 21</a></h1>
<div class=thumbnails>
<a href=/inscription/1{64}i1><iframe .* src=/preview/1{64}i1></iframe></a>
<a href=/inscription/2{64}i2><iframe .* src=/preview/2{64}i2></iframe></a>
Expand Down
23 changes: 21 additions & 2 deletions static/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,32 @@ ol, ul {
}
}

.blocks {
.block-list {
font-family: monospace, monospace;
list-style-position: inside;
padding-inline-start: 1rem;
white-space: nowrap;
}

.block {
background-color: var(--light-bg);
box-shadow: rgba(0, 0, 0, 0.16) 0px 1px 4px, var(--light-bg) 0px 0px 0px 3px;
margin: 3%;
padding: 0.5%;
text-align: center;
}

.block a {
color: var(--light-fg);
margin-top: 1%;
}

.block h2 {
margin: 1%;
}

.light-fg a {
color: var(--light-fg);
}
.center {
text-align: center;
}
Expand Down
23 changes: 13 additions & 10 deletions templates/home.html
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
%% if !&self.inscriptions.is_empty() {
<h2>Latest Inscriptions</h2>
<div class=thumbnails>
%% for id in &self.inscriptions {
{{Iframe::thumbnail(*id)}}
%% for (i, hash) in self.blocks.iter().enumerate() {
%% if let Some(inscription_ids) = &self.featured_blocks.get(hash) {
<div class=block>
<h2><a href=/block/{{ self.last - i as u64 }}>Block {{ self.last - i as u64 }}</a></h2>
<div class=thumbnails>
%% for id in *inscription_ids {
{{ Iframe::thumbnail(*id) }}
%% }
</div>
</div>
<div class=center><a href=/inscriptions>more</a></div>
%% } else {
%% if i == self.featured_blocks.len() {
<ol start={{ self.last - self.featured_blocks.len() as u64 }} reversed class=block-list>
%% }
<li><a href=/block/{{ hash }}>{{ hash }}</a></li>
%% }
<h2>Latest Blocks</h2>
<ol start={{self.last}} reversed class=blocks>
%% for hash in &self.blocks {
<li><a href=/block/{{hash}}>{{hash}}</a></li>
%% }
</ol>
2 changes: 1 addition & 1 deletion templates/inscriptions-block.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<h1>Inscriptions in <a href=/block/{{ &self.block }}>Block {{ &self.block }}</a></h1>
<h1 class=light-fg>Inscriptions in <a href=/block/{{ &self.block }}>Block {{ &self.block }}</a></h1>
<div class=thumbnails>
%% for id in &self.inscriptions {
{{ Iframe::thumbnail(*id) }}
Expand Down
43 changes: 0 additions & 43 deletions tests/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,49 +195,6 @@ fn inscription_content() {
assert_eq!(response.bytes().unwrap(), "FOO");
}

#[test]
fn home_page_includes_latest_inscriptions() {
let rpc_server = test_bitcoincore_rpc::spawn();
create_wallet(&rpc_server);

let Inscribe { inscription, .. } = inscribe(&rpc_server);

TestServer::spawn_with_args(&rpc_server, &[]).assert_response_regex(
"/",
format!(
".*<h2>Latest Inscriptions</h2>
<div class=thumbnails>
<a href=/inscription/{inscription}><iframe .*></a>
</div>.*",
),
);
}

#[test]
fn home_page_inscriptions_are_sorted() {
let rpc_server = test_bitcoincore_rpc::spawn();
create_wallet(&rpc_server);

let mut inscriptions = String::new();

for _ in 0..8 {
let Inscribe { inscription, .. } = inscribe(&rpc_server);
inscriptions.insert_str(
0,
&format!("\n <a href=/inscription/{inscription}><iframe .*></a>"),
);
}

TestServer::spawn_with_args(&rpc_server, &[]).assert_response_regex(
"/",
format!(
".*<h2>Latest Inscriptions</h2>
<div class=thumbnails>{inscriptions}
</div>.*"
),
);
}

#[test]
fn inscriptions_page() {
let rpc_server = test_bitcoincore_rpc::spawn();
Expand Down

0 comments on commit 9eb09aa

Please sign in to comment.