Skip to content

Commit

Permalink
✨ Tab loading spinner
Browse files Browse the repository at this point in the history
  • Loading branch information
trickypr committed Nov 10, 2023
1 parent 536e47d commit 28c0bda
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 8 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
},
"dependencies": {
"@catppuccin/palette": "^0.2.0",
"fnts": "^2.0.1",
"mitt": "^3.0.1",
"remixicon": "^3.5.0",
"snarkdown": "^2.0.0"
Expand Down
15 changes: 14 additions & 1 deletion pnpm-lock.yaml

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

18 changes: 14 additions & 4 deletions src/content/browser/components/tabs/Tab.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
import { type Tab } from './tab'
import { closeTab, moveTabBefore, moveTabAfter } from '../../lib/globalApi'
import type { DragEventHandler } from 'svelte/elements'
import Spinner from '../../../shared/components/Spinner.svelte'
export let tab: Tab
export let selectedTab: number
let lastDragIsBefore: undefined | boolean
const { title, icon, uri } = tab
const { title, icon, uri, loading } = tab
$: tab.getId() == selectedTab && (document.title = $title)
Expand Down Expand Up @@ -53,8 +54,12 @@
aria-selected={tab.getId() == selectedTab}
draggable="true"
>
{#if $icon}
<img class="tab__icon" src={$icon} alt="favicon" />
{#if $loading}
<div class="tab__start-item">
<Spinner />
</div>
{:else if $icon}
<img class="tab__icon tab__start-item" src={$icon} alt="favicon" />
{/if}
<span>{$title || $uri.asciiSpec}</span>
<button
Expand Down Expand Up @@ -121,9 +126,14 @@
background: var(--surface-2);
}
.tab__start-item {
margin-right: 0.5rem;
/* The spinner uses em to size, we can resize it with font size */
font-size: 1rem;
}
.tab__icon {
height: 1.5rem;
width: 1.5rem;
margin-right: 0.5rem;
}
</style>
46 changes: 43 additions & 3 deletions src/content/browser/components/tabs/tab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ export class Tab {
public canGoBack = writable(false)
public canGoForward = writable(false)

public loading = writable(false)
public loadingProgress = writable(0)

/**
* This is used by the omnibox to determine if text input should be focused.
*/
Expand Down Expand Up @@ -99,10 +102,15 @@ export class Tab {
this.progressListener.events.on('locationChange', (event) => {
if (!event.aWebProgress.isTopLevel) return

this.icon.set(null)

this.uri.set(event.aLocation)
this.canGoBack.set(this.browserElement.canGoBack)
this.canGoForward.set(this.browserElement.canGoForward)
})

this.progressListener.events.on('progressPercent', this.loadingProgress.set)
this.progressListener.events.on('loadingChange', this.loading.set)
}

public async setContainer(container: HTMLElement) {
Expand Down Expand Up @@ -173,6 +181,8 @@ type TabProgressListenerEvent = {
aLocation: nsIURIType
aFlags: number
} & TabProgressListenerEventDefaults
progressPercent: number
loadingChange: boolean
}

let progressListenerCounter = 0
Expand All @@ -199,6 +209,10 @@ class TabProgressListener
)
}

/**
* This request is identical to {@link onProgressChange64}. The only
* difference is that the c++ impl uses `long long`s instead of `long`s
*/
onProgressChange64(
aWebProgress: nsIWebProgressType,
aRequest: nsIRequestType,
Expand All @@ -207,7 +221,14 @@ class TabProgressListener
aCurTotalProgress: number,
aMaxTotalProgress: number,
): void {
console.log('onProgressChange64')
return this.onProgressChange(
aWebProgress,
aRequest,
aCurSelfProgress,
aMaxSelfProgress,
aCurTotalProgress,
aMaxTotalProgress,
)
}

onRefreshAttempted(
Expand All @@ -225,8 +246,22 @@ class TabProgressListener
aStateFlags: number,
aStatus: number,
): void {
console.log('onStateChange')
if (!aWebProgress.isTopLevel) return
if (
aStateFlags & Ci.nsIWebProgressListener.STATE_START &&
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK
) {
this.events.emit('loadingChange', true)
}

if (
aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK
) {
this.events.emit('loadingChange', false)
}
}

onProgressChange(
aWebProgress: nsIWebProgressType,
aRequest: nsIRequestType,
Expand All @@ -235,8 +270,13 @@ class TabProgressListener
aCurTotalProgress: number,
aMaxTotalProgress: number,
): void {
console.log('onProgressChange')
if (!aWebProgress || !aWebProgress.isTopLevel) return
this.events.emit(
'progressPercent',
aMaxTotalProgress !== 0 ? aCurTotalProgress / aMaxTotalProgress : 0,
)
}

onLocationChange(
aWebProgress: nsIWebProgressType,
aRequest: nsIRequestType,
Expand Down
4 changes: 4 additions & 0 deletions src/content/browser/lib/binaryEnums.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { curry } from 'fnts'

export const isBitSet = curry((bit: number, num: number) => (num & bit) !== 0)
export const isBitSetFast = curry((bit: number, num: number) => num & bit)
28 changes: 28 additions & 0 deletions src/content/shared/components/Spinner.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<div class="spinner" />

<style>
.spinner {
background-color: var(--active);
display: block;
width: 0.75em;
height: 0.75em;
border-radius: 0.25em;
margin: 0.125rem;
animation-name: spinner;
animation-duration: 1s;
animation-iteration-count: infinite;
}
@keyframes spinner {
from {
transform: rotate(0deg);
}
to {
transform: rotate(90deg);
}
}
</style>

0 comments on commit 28c0bda

Please sign in to comment.