|
4 | 4 | import { loadMultiscales, ngffTable } from "./tableStore"; |
5 | 5 | import Thumbnail from "./Thumbnail.svelte"; |
6 | 6 | import { onDestroy } from "svelte"; |
7 | | -
|
| 7 | + import copyImage from "/copy.png"; |
| 8 | + import checkImage from "/ome-logomark.svg"; |
| 9 | + import externalDataImage from "/original-data.svg"; |
8 | 10 | export let rowData; |
9 | 11 | export let textFilter; |
10 | 12 | export let sortedBy = undefined; |
|
76 | 78 | }); |
77 | 79 |
|
78 | 80 | $: description = (textFilter != "" && rowData.description?.toLowerCase().includes(textFilter.toLowerCase())) ? rowData.description : ""; |
| 81 | +
|
| 82 | + let isShaking = false; |
| 83 | + // Adapted from https://github.com/IDR/ome-ngff-samples/blob/main/index.md |
| 84 | + function copyTextToClipboard(text) { |
| 85 | + var textArea = document.createElement("textarea"); |
| 86 | + // Place in the top-left corner of screen regardless of scroll position. |
| 87 | + textArea.style.position = 'fixed'; |
| 88 | + textArea.value = text; |
| 89 | + document.body.appendChild(textArea); |
| 90 | + textArea.focus(); |
| 91 | + textArea.select(); |
| 92 | + let successful = false; |
| 93 | + try { |
| 94 | + successful = document.execCommand("copy"); |
| 95 | + } catch (err) { |
| 96 | + console.log("Oops, unable to copy"); |
| 97 | + } |
| 98 | + document.body.removeChild(textArea); |
| 99 | +
|
| 100 | + if (successful) { |
| 101 | + // trigger shake for 1s |
| 102 | + isShaking = true; |
| 103 | + setTimeout(() => (isShaking = false), 1000); |
| 104 | + } |
| 105 | +}; |
79 | 106 | </script> |
80 | 107 |
|
81 | 108 | <div class="zarr-list-item"> |
|
85 | 112 | {/if} |
86 | 113 | </div> |
87 | 114 | <div> |
88 | | - <div title="{rowData.url}"><strong>{@html formatUrlToName(rowData.url)}</strong></div> |
| 115 | + <div title="{rowData.url}"><strong>{@html formatUrlToName(rowData.url)} </strong> |
| 116 | +
|
| 117 | + </div> |
89 | 118 | <div class={textFilter == "" ? "hideOnSmall" : ""}> |
90 | 119 | <!-- If we're not filtering by text (name/description) then hide the name on small screen --> |
91 | 120 | {@html rowData.name ? rowData.name.replaceAll(textFilter, `<mark>${textFilter}</mark>`) : ""} |
|
102 | 131 | </div> |
103 | 132 | {/if} |
104 | 133 | <div> |
105 | | - Open in <a |
106 | | - title="Open in Validator: {rowData.url}" |
107 | | - href="https://ome.github.io/ome-ngff-validator/?source={rowData.url}" |
108 | | - target="_blank" |
109 | | - >OME-Validator. |
110 | | - </a> |
| 134 | + <button |
| 135 | + class="no_border" |
| 136 | + class:shake={isShaking} |
| 137 | + title="Copy S3 URL to clipboard" |
| 138 | + on:click={(event) => copyTextToClipboard(rowData.url) |
| 139 | + } |
| 140 | + > |
| 141 | + <img class="icon" src={copyImage} /> |
| 142 | + </button> |
| 143 | +
|
| 144 | + <a title="Validate NGFF with 'ome-ngff-validator' in new browser tab" target="_blank" |
| 145 | + href="https://ome.github.io/ome-ngff-validator/?source={rowData.url}"> |
| 146 | + <img class="icon" style="opacity: 0.9" src={checkImage}/></a> |
111 | 147 |
|
112 | 148 | {#if rowData.origin } |
113 | | - Browse <a |
114 | | - title="Link to original data: {rowData.origin}" |
| 149 | +
|
| 150 | + <a title="Link to original data: {rowData.origin}" |
115 | 151 | href={rowData.origin} |
116 | | - target="_blank" |
117 | | - >Original data</a>. |
| 152 | + target="_blank"> |
| 153 | + <img class="icon" style="opacity: 0.9" src={externalDataImage}/></a> |
| 154 | +
|
118 | 155 | {/if} |
119 | 156 | </div> |
120 | 157 | <div> |
|
155 | 192 | display: none; |
156 | 193 | } |
157 | 194 | } |
| 195 | +
|
| 196 | +
|
| 197 | + :root { |
| 198 | + --icon-size: 20px; |
| 199 | +} |
| 200 | +
|
| 201 | + .icon { |
| 202 | + width: var(--icon-size); |
| 203 | + height: var(--icon-size); |
| 204 | + aspect-ratio: 1 / 1; |
| 205 | + } |
| 206 | + .no_border { |
| 207 | + border: none; |
| 208 | + background: none; |
| 209 | + padding: 0; |
| 210 | + } |
| 211 | +
|
| 212 | + .shake { |
| 213 | + animation: 0.1s linear 0s infinite alternate seesaw; |
| 214 | + } |
| 215 | +
|
| 216 | + @keyframes seesaw { from { transform: rotate(-0.05turn) } to { transform: rotate(0.05turn); } } |
| 217 | +
|
158 | 218 | </style> |
0 commit comments