mirror of
https://github.com/aleksey-hoffman/sigma-file-manager.git
synced 2026-10-18 17:20:21 -05:00
Fix (linux, Flatpak): app panics on launch - bundle libayatana-appindicator, update GNOME runtime to 51 (#551)
* Fix (linux, Flatpak): app panics on launch (Failed to load ayatana-appindicator3) - Bundle libayatana-appindicator via Flathub shared-modules - Update GNOME runtime from EOL 48 to 51 * Dev: lint - Fix existing ESLint and Stylelint errors from main - Ignore Flatpak shared-modules and build dirs in ESLint
This commit is contained in:
1 parent
61cdbb61f2
commit
3df1570d17
18 files changed
+121
-36
No files matched your search
@@ -287,7 +287,7 @@ jobs:
|
||||
run: |
|
||||
sudo apt-get install -y flatpak flatpak-builder
|
||||
flatpak remote-add --if-not-exists --user flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||
flatpak install -y --noninteractive --user flathub org.gnome.Platform//48 org.gnome.Sdk//48
|
||||
flatpak install -y --noninteractive --user flathub org.gnome.Platform//51 org.gnome.Sdk//51
|
||||
|
||||
- name: Build Flatpak bundle
|
||||
if: matrix.platform == 'linux'
|
||||
|
||||
@@ -33,3 +33,4 @@ flatpak/.deb-input/
|
||||
flatpak/.build/
|
||||
flatpak/.repo/
|
||||
flatpak/output/
|
||||
.flatpak-builder/
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "flatpak/shared-modules"]
|
||||
path = flatpak/shared-modules
|
||||
url = https://github.com/flathub/shared-modules.git
|
||||
+4
-1
@@ -7,7 +7,10 @@ import checkFile from 'eslint-plugin-check-file';
|
||||
import pluginVueI18n from '@intlify/eslint-plugin-vue-i18n';
|
||||
|
||||
export default defineConfigWithVueTs(
|
||||
globalIgnores(['**/dist/**', '**/dist-ssr/**', '**/coverage/**', '**/e2e-webdriver/**', 'src-tauri/**']),
|
||||
globalIgnores([
|
||||
'**/dist/**', '**/dist-ssr/**', '**/coverage/**', '**/e2e-webdriver/**', 'src-tauri/**',
|
||||
'flatpak/shared-modules/', 'flatpak/.build/', 'flatpak/.repo/', 'flatpak/.deb-input/', 'flatpak/output/', '.flatpak-builder/',
|
||||
]),
|
||||
pluginVue.configs['flat/strongly-recommended'],
|
||||
vueTsConfigs.recommended,
|
||||
pluginStylistic.configs.customize({
|
||||
|
||||
@@ -10,7 +10,8 @@ repo_directory="$flatpak_directory/.repo"
|
||||
output_directory="$flatpak_directory/output"
|
||||
manifest_path="$flatpak_directory/com.sigma-file-manager.app.yml"
|
||||
app_id="com.sigmafilemanager.app"
|
||||
runtime_ref="org.gnome.Platform/x86_64/48"
|
||||
runtime_version="51"
|
||||
runtime_ref="org.gnome.Platform/x86_64/${runtime_version}"
|
||||
|
||||
version="$(node -p "require('$root_directory/package.json').version")"
|
||||
bundle_path="$output_directory/Sigma-File-Manager-${version}-linux.flatpak"
|
||||
@@ -62,9 +63,17 @@ ensure_flatpak_runtime() {
|
||||
fi
|
||||
|
||||
flatpak remote-add --if-not-exists --user flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||
flatpak install -y --noninteractive --user flathub org.gnome.Platform//48 org.gnome.Sdk//48
|
||||
flatpak install -y --noninteractive --user flathub "org.gnome.Platform//${runtime_version}" "org.gnome.Sdk//${runtime_version}"
|
||||
}
|
||||
|
||||
ensure_shared_modules() {
|
||||
if [ -f "$flatpak_directory/shared-modules/libayatana-appindicator/libayatana-appindicator-gtk3.json" ]; then
|
||||
return
|
||||
fi
|
||||
git -C "$root_directory" submodule update --init flatpak/shared-modules
|
||||
}
|
||||
|
||||
ensure_shared_modules
|
||||
deb_package="$(ensure_deb_package)"
|
||||
mkdir -p "$deb_input_directory" "$output_directory"
|
||||
cp "$deb_package" "$deb_input_directory/sigma-file-manager.deb"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
id: com.sigmafilemanager.app
|
||||
runtime: org.gnome.Platform
|
||||
runtime-version: '48'
|
||||
runtime-version: '51'
|
||||
sdk: org.gnome.Sdk
|
||||
command: sigma-file-manager
|
||||
appstream-compose: false
|
||||
@@ -22,6 +22,10 @@ finish-args:
|
||||
- --filesystem=xdg-config/autostart:create
|
||||
|
||||
modules:
|
||||
# Tauri's tray icon (libappindicator-sys) dlopens libayatana-appindicator3 at startup,
|
||||
# which the GNOME runtime doesn't ship.
|
||||
- shared-modules/libayatana-appindicator/libayatana-appindicator-gtk3.json
|
||||
|
||||
- name: sigma-file-manager
|
||||
buildsystem: simple
|
||||
sources:
|
||||
|
||||
Submodule
+1
Submodule flatpak/shared-modules added at a58e654b91.
@@ -26,6 +26,7 @@ const props = withDefaults(defineProps<{
|
||||
align?: PopoverContentProps['align'];
|
||||
side?: PopoverContentProps['side'];
|
||||
}>(), {
|
||||
tagSummary: undefined,
|
||||
allowCreate: true,
|
||||
fullWidth: true,
|
||||
align: 'end',
|
||||
@@ -33,7 +34,7 @@ const props = withDefaults(defineProps<{
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
open: [];
|
||||
'open': [];
|
||||
'open-change': [open: boolean];
|
||||
'toggle-tag': [tagId: string];
|
||||
'create-tag': [name: string];
|
||||
@@ -100,6 +101,7 @@ watch(() => props.isSelectorMounted, (mounted) => {
|
||||
|
||||
if (mounted) {
|
||||
showEditor.value = true;
|
||||
|
||||
if (prefersReducedMotion()) {
|
||||
isExpanded.value = true;
|
||||
return;
|
||||
@@ -165,11 +167,11 @@ onUnmounted(() => {
|
||||
:title="resolvedTagSummary"
|
||||
@click="emit('open')"
|
||||
>
|
||||
<TagIcon class="tag-selector__trigger-icon-plus" />
|
||||
<TagOverflowList
|
||||
v-if="overflowTags.length > 0"
|
||||
:tags="overflowTags"
|
||||
/>
|
||||
<TagIcon class="tag-selector__trigger-icon-plus" />
|
||||
<TagOverflowList
|
||||
v-if="overflowTags.length > 0"
|
||||
:tags="overflowTags"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -4,7 +4,9 @@ Copyright © 2021 - present Aleksey Hoffman. All rights reserved.
|
||||
-->
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, nextTick, onBeforeUnmount, ref, watch } from 'vue';
|
||||
import {
|
||||
computed, nextTick, onBeforeUnmount, ref, watch,
|
||||
} from 'vue';
|
||||
import { convertFileSrc } from '@tauri-apps/api/core';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { FileIcon, ImageIcon, SearchIcon, XIcon } from '@lucide/vue';
|
||||
|
||||
@@ -315,7 +315,10 @@ describe('clipboard store', () => {
|
||||
});
|
||||
|
||||
it('saves a replacement clipboard image after a pending save finishes', async () => {
|
||||
const firstSave = createDeferred<{ path: string; sizeBytes: number }>();
|
||||
const firstSave = createDeferred<{
|
||||
path: string;
|
||||
sizeBytes: number;
|
||||
}>();
|
||||
let saveCount = 0;
|
||||
invokeMock.mockImplementation(async (commandName: string) => {
|
||||
if (commandName === 'save_system_clipboard_image_to_temp') {
|
||||
|
||||
@@ -284,8 +284,14 @@ describe('user stats tagged item removal', () => {
|
||||
path: item.path,
|
||||
tagIds: item.tagIds,
|
||||
}))).toEqual([
|
||||
{ path: '/both', tagIds: ['tag-personal'] },
|
||||
{ path: '/personal-1', tagIds: ['tag-personal'] },
|
||||
{
|
||||
path: '/both',
|
||||
tagIds: ['tag-personal'],
|
||||
},
|
||||
{
|
||||
path: '/personal-1',
|
||||
tagIds: ['tag-personal'],
|
||||
},
|
||||
]);
|
||||
expect(lazyStoreSetMock).toHaveBeenCalledWith('taggedItems', store.taggedItems);
|
||||
});
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
}
|
||||
|
||||
.animate-dashboard-content {
|
||||
opacity: 0;
|
||||
animation-fill-mode: both;
|
||||
animation-name: animate-dashboard-content;
|
||||
animation-timing-function: ease-out;
|
||||
animation-fill-mode: both;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
@keyframes animate-dashboard-content {
|
||||
|
||||
@@ -23,12 +23,21 @@ describe('formatDashboardFileSize', () => {
|
||||
|
||||
describe('formatDashboardDirectorySize', () => {
|
||||
it('formats a completed directory size', () => {
|
||||
expect(formatDashboardDirectorySize({ status: 'Complete', size: 1048576 })).toBe('1.0 MB');
|
||||
expect(formatDashboardDirectorySize({
|
||||
status: 'Complete',
|
||||
size: 1048576,
|
||||
})).toBe('1.0 MB');
|
||||
});
|
||||
|
||||
it('uses a dash while a directory size is still unknown', () => {
|
||||
expect(formatDashboardDirectorySize(undefined)).toBe(UNKNOWN_DASHBOARD_ITEM_SIZE);
|
||||
expect(formatDashboardDirectorySize({ status: 'Loading', size: 0 })).toBe(UNKNOWN_DASHBOARD_ITEM_SIZE);
|
||||
expect(formatDashboardDirectorySize({ status: 'Error', size: 0 })).toBe(UNKNOWN_DASHBOARD_ITEM_SIZE);
|
||||
expect(formatDashboardDirectorySize({
|
||||
status: 'Loading',
|
||||
size: 0,
|
||||
})).toBe(UNKNOWN_DASHBOARD_ITEM_SIZE);
|
||||
expect(formatDashboardDirectorySize({
|
||||
status: 'Error',
|
||||
size: 0,
|
||||
})).toBe(UNKNOWN_DASHBOARD_ITEM_SIZE);
|
||||
});
|
||||
});
|
||||
@@ -31,7 +31,10 @@ describe('sortTaggedItems', () => {
|
||||
createItem('/docs/alpha', 3),
|
||||
createItem('/other/beta', 2),
|
||||
];
|
||||
const getName = (item: TaggedItem) => item.path.split('/').at(-1) ?? item.path;
|
||||
|
||||
function getName(item: TaggedItem) {
|
||||
return item.path.split('/').at(-1) ?? item.path;
|
||||
}
|
||||
|
||||
expect(sortTaggedItems(items, 'name', getName).map(getName)).toEqual([
|
||||
'alpha',
|
||||
|
||||
@@ -43,8 +43,14 @@ describe('getTaggedSections', () => {
|
||||
tagId: section.tag.id,
|
||||
paths: section.items.map(item => item.path),
|
||||
}))).toEqual([
|
||||
{ tagId: 'work', paths: ['/work-1', '/work-2'] },
|
||||
{ tagId: 'personal', paths: ['/personal-1', '/work-2'] },
|
||||
{
|
||||
tagId: 'work',
|
||||
paths: ['/work-1', '/work-2'],
|
||||
},
|
||||
{
|
||||
tagId: 'personal',
|
||||
paths: ['/personal-1', '/work-2'],
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -68,8 +74,14 @@ describe('getTaggedSections', () => {
|
||||
tagId: section.tag.id,
|
||||
count: section.items.length,
|
||||
}))).toEqual([
|
||||
{ tagId: 'work', count: 1 },
|
||||
{ tagId: 'archive', count: 0 },
|
||||
{
|
||||
tagId: 'work',
|
||||
count: 1,
|
||||
},
|
||||
{
|
||||
tagId: 'archive',
|
||||
count: 0,
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
@@ -100,9 +112,18 @@ describe('getDashboardTagSections', () => {
|
||||
tagId: section.tag.id,
|
||||
count: section.items.length,
|
||||
}))).toEqual([
|
||||
{ tagId: 'work', count: 1 },
|
||||
{ tagId: 'archive', count: 0 },
|
||||
{ tagId: ORPHANED_TAG_ID, count: 1 },
|
||||
{
|
||||
tagId: 'work',
|
||||
count: 1,
|
||||
},
|
||||
{
|
||||
tagId: 'archive',
|
||||
count: 0,
|
||||
},
|
||||
{
|
||||
tagId: ORPHANED_TAG_ID,
|
||||
count: 1,
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -163,21 +163,30 @@ describe('virtual-location-action-target', () => {
|
||||
expect(resolveDuplicateCurrentTabShortcutTarget(
|
||||
'C:/Users',
|
||||
getVirtualLocationActionContext([], 'C:/Users'),
|
||||
)).toEqual({ kind: 'clone-path', path: 'C:/Users' });
|
||||
)).toEqual({
|
||||
kind: 'clone-path',
|
||||
path: 'C:/Users',
|
||||
});
|
||||
});
|
||||
|
||||
it('clones the locations virtual path when nothing is selected', () => {
|
||||
expect(resolveDuplicateCurrentTabShortcutTarget(
|
||||
LOCATIONS_VIRTUAL_PATH,
|
||||
getVirtualLocationActionContext([], LOCATIONS_VIRTUAL_PATH),
|
||||
)).toEqual({ kind: 'clone-path', path: LOCATIONS_VIRTUAL_PATH });
|
||||
)).toEqual({
|
||||
kind: 'clone-path',
|
||||
path: LOCATIONS_VIRTUAL_PATH,
|
||||
});
|
||||
});
|
||||
|
||||
it('clones the wsl host virtual path when nothing is selected', () => {
|
||||
expect(resolveDuplicateCurrentTabShortcutTarget(
|
||||
WSL_HOST_VIRTUAL_PATH,
|
||||
getVirtualLocationActionContext([], WSL_HOST_VIRTUAL_PATH),
|
||||
)).toEqual({ kind: 'clone-path', path: WSL_HOST_VIRTUAL_PATH });
|
||||
)).toEqual({
|
||||
kind: 'clone-path',
|
||||
path: WSL_HOST_VIRTUAL_PATH,
|
||||
});
|
||||
});
|
||||
|
||||
it('opens the selected location when browsing virtual locations', () => {
|
||||
|
||||
@@ -58,7 +58,10 @@ export const DASHBOARD_CARD_ENTRANCE: StaggerAnimationOptions = {
|
||||
|
||||
export function getDashboardContentEntranceBinding(): {
|
||||
class: string;
|
||||
style: { animationDelay: string; animationDuration: string };
|
||||
style: {
|
||||
animationDelay: string;
|
||||
animationDuration: string;
|
||||
};
|
||||
} {
|
||||
return {
|
||||
class: DASHBOARD_CONTENT_ENTRANCE_CLASS,
|
||||
|
||||
@@ -100,9 +100,12 @@ export function getVirtualLocationActionContext(
|
||||
};
|
||||
}
|
||||
|
||||
export type DuplicateCurrentTabShortcutTarget =
|
||||
| { kind: 'open-selection' }
|
||||
| { kind: 'clone-path'; path: string };
|
||||
export type DuplicateCurrentTabShortcutTarget
|
||||
= | { kind: 'open-selection' }
|
||||
| {
|
||||
kind: 'clone-path';
|
||||
path: string;
|
||||
};
|
||||
|
||||
export function resolveDuplicateCurrentTabShortcutTarget(
|
||||
currentDirectoryPath: string | null | undefined,
|
||||
@@ -116,5 +119,8 @@ export function resolveDuplicateCurrentTabShortcutTarget(
|
||||
return null;
|
||||
}
|
||||
|
||||
return { kind: 'clone-path', path: currentDirectoryPath };
|
||||
return {
|
||||
kind: 'clone-path',
|
||||
path: currentDirectoryPath,
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user