Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ jobs:
- name: End-to-end test
run: npx playwright test -c e2e/playci.config.ts
### Uncomment when you need to re-extract snapshots
# - name: Extract snapshots
# if: always()
# uses: actions/upload-artifact@v4
# with:
# name: ci_actual_snapshots
# path: e2e/results/manual/output
- name: Extract snapshots
if: always()
uses: actions/upload-artifact@v4
with:
name: ci_actual_snapshots
path: e2e/results/manual/output
19 changes: 19 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
"postinstall": "git config --local include.path ../.gitconfig && python3 -m venv .venv && cd tools && node pyrun.mjs python -m pip install -U pip && node pyrun.mjs pip install -r requirements.txt"
},
"dependencies": {
"@phosphor-icons/vue": "^2.2.1",
"axios": "^1.12.0",
"bigint-isqrt": "^0.3.2",
"bigint-mod-arith": "^3.3.1",
Expand Down
8 changes: 5 additions & 3 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
</script>

<!-- Global styles. This style tag is explicitly unscoped. -->
<style>
<style lang="scss">
#container {
display: flex;
flex-direction: column;
Expand Down Expand Up @@ -86,6 +86,8 @@
--ns-font-weight-medium: 500;

/* Dimensions */
/* TODO: compute this dynamically */
--ns-mobile-navbar-height: 45px;
--ns-desktop-navbar-height: 76px;
--ns-desktop-tab-width: 300px;
--ns-specimen-card-width: 216px;
Expand All @@ -106,8 +108,8 @@
// Large devices (desktops)
@media (min-width: $desktop-breakpoint) { ... }
*/
--ns-breakpoint-mobile: $mobile-breakpoint;
--ns-breakpoint-tablet: $tablet-breakpoint;
--ns-breakpoint-mobile: #{$mobile-breakpoint};
--ns-breakpoint-tablet: #{$tablet-breakpoint};
/* Not actually used at the moment:
--ns-breakpoint-desktop: 1200px;
*/
Expand Down
8 changes: 6 additions & 2 deletions src/components/SpecimenBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<label>
Specimen name
<input
id="spec-name"
class="spec-name"
type="text"
:value="specimen.name"
@keyup.enter="blurName()"
Expand Down Expand Up @@ -117,7 +117,11 @@
}

function blurName() {
window.document.getElementById('spec-name')?.blur()
for (const input of Array.from(
document.getElementsByClassName('spec-name')
) as HTMLInputElement[]) {
input.blur()
}
}

function refresh() {
Expand Down
3 changes: 1 addition & 2 deletions src/components/Tab.vue
Original file line number Diff line number Diff line change
Expand Up @@ -309,8 +309,7 @@
display: none;
}
.tab {
width: 300px;
height: fit-content;
width: 100%;
}
.content {
padding: 0px 16px 16px 16px;
Expand Down
128 changes: 110 additions & 18 deletions src/views/Scope.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,40 @@ visualizers you can select.
id="specimen-bar-desktop"
:specimen
@update-specimen-name="handleSpecimenUpdate" />
<div id="phone-opener-container">
<button
aria-controls="sequenceTab"
:aria-expanded="Boolean(sequenceTabOpen)"
class="phone-opener"
type="button"
@click="
() => {
sequenceTabOpen = !sequenceTabOpen
visualizerTabOpen = false
}
">
<PhDna
alt="Toggle sequence tab"
:size="24"
color="currentColor" />
</button>
<button
aria-controls="visualizerTab"
:aria-expanded="Boolean(visualizerTabOpen)"
class="phone-opener"
type="button"
@click="
() => {
visualizerTabOpen = !visualizerTabOpen
sequenceTabOpen = false
}
">
<PhMicroscope
alt="Toggle visualizer tab"
:size="24"
color="currentColor" />
</button>
</div>
</NavBar>
<div id="specimen-container">
<SwitcherModal
Expand All @@ -70,10 +104,11 @@ visualizers you can select.
changeVisualizerOpen = false
}
" />
<tab
<Tab
id="sequenceTab"
class="tab docked"
docked="top-right"
:class="{visible: sequenceTabOpen}"
:last-coords-x="Math.floor(tabWidth / 3)"
:last-coords-y="Math.floor(tabWidth / 3)">
<ParamEditor
Expand All @@ -87,10 +122,11 @@ visualizers you can select.
updateURL()
}
" />
</tab>
<tab
id="visualiserTab"
</Tab>
<Tab
id="visualizerTab"
class="tab docked"
:class="{visible: visualizerTabOpen}"
docked="bottom-right"
last-dropzone="bottom-right"
:last-coords-x="Math.floor((2 * tabWidth) / 3)"
Expand All @@ -105,7 +141,7 @@ visualizers you can select.
updateURL()
}
" />
</tab>
</Tab>
<SpecimenBar
id="specimen-bar-phone"
class="specimen-bar"
Expand Down Expand Up @@ -162,6 +198,7 @@ visualizers you can select.
</template>

<script lang="ts">
import {PhDna, PhMicroscope} from '@phosphor-icons/vue'
import NavBar from './minor/NavBar.vue'
import SpecimenBar from '../components/SpecimenBar.vue'
import {clearErrorOverlay} from '@/shared/alertMessage'
Expand Down Expand Up @@ -294,6 +331,7 @@ visualizers you can select.
* Used when the window is resized.
*/
export function positionAndSizeAllTabs(): void {
if (isMobile()) return
// First reset the "empty" classes and recompute them, just in case:
document
.querySelectorAll('.dropzone')
Expand Down Expand Up @@ -372,6 +410,9 @@ visualizers you can select.
const changeSequenceOpen = ref(false)
const changeVisualizerOpen = ref(false)

const sequenceTabOpen = ref(false)
const visualizerTabOpen = ref(false)

const router = useRouter()
const route = useRoute()

Expand Down Expand Up @@ -619,13 +660,31 @@ visualizers you can select.

<style scoped lang="scss">
// mobile styles
#phone-opener-container {
align-items: center;
display: flex;
gap: 0.5em;
margin-right: 0.5em;
}

.phone-opener {
/* remove button styles */
background: none;
border-style: none;

/* center contents */
display: inline-flex;
align-items: center;
}

.navbar {
display: unset;
}
#specimen-bar-desktop {
display: none;
}
#main {
flex: 1;
display: flex;
height: 100%;
}
Expand All @@ -636,6 +695,10 @@ visualizers you can select.
min-height: fit-content;
padding-left: auto;
padding-right: auto;

@media (max-width: $mobile-breakpoint) {
flex: 1;
}
}
#canvas-container {
flex: 1;
Expand All @@ -647,7 +710,6 @@ visualizers you can select.
order: 1;
z-index: -1;
border-bottom: 1px solid var(--ns-color-black);
height: 300px;
width: 100%;
}
.dropzone-container {
Expand All @@ -662,27 +724,48 @@ visualizers you can select.
display: none;
}
#sequenceTab {
width: 100%;
padding-left: auto;
padding-right: auto;
order: 3;
border-bottom: 1px solid var(--ns-color-black);
height: fit-content;
}
#visualiserTab {
#visualizerTab {
width: 100%;
padding-left: auto;
padding-right: auto;
order: 4;
border-bottom: 1px solid var(--ns-color-black);
height: fit-content;
}
#specimen-bar-phone {
order: 2;
padding-left: auto;
padding-right: auto;
padding: 8px;
border-bottom: 1px solid var(--ns-color-black);
position: fixed;
bottom: 0;
z-index: 1;
left: 0;
background: var(--ns-color-white);

/* align with label */
:deep(.spec-name) {
padding-left: 0;
}
}

@media (max-width: $mobile-breakpoint) {
.tab {
background: var(--ns-color-white);
bottom: 0;
height: 0;
overflow: hidden;
position: absolute;
transition: height 150ms ease-in-out;
z-index: 2;

&.visible {
height: calc(0.5 * (100vh - var(--ns-mobile-navbar-height)));
overflow: auto;
}
}
}

// tablet & desktop styles
@media (min-width: $tablet-breakpoint) {
#specimen-bar-desktop {
Expand All @@ -696,7 +779,8 @@ visualizers you can select.
border: 0px;
}
#sequenceTab,
#visualiserTab {
#visualizerTab {
display: block;
width: var(--ns-desktop-tab-width);
}
#specimen-container {
Expand All @@ -708,7 +792,6 @@ visualizers you can select.
}

#canvas-container {
height: unset;
order: unset;
flex: 1;
position: relative;
Expand Down Expand Up @@ -773,8 +856,17 @@ visualizers you can select.

.tab {
width: 300px;
position: absolute;
order: unset;
height: fit-content;
position: absolute;

padding-left: auto;
padding-right: auto;
border-bottom: 1px solid var(--ns-color-black);
}

#phone-opener-container {
display: none;
}
}
</style>
Loading
Loading