Compare commits
9 commits
Author | SHA1 | Date | |
---|---|---|---|
324857ad3c | |||
10b01202e9 | |||
6a5132accd | |||
5ca74febe1 | |||
32b86e7285 | |||
532a493a62 | |||
f44df5f415 | |||
95cc608edf | |||
1881e511a0 |
17 changed files with 208 additions and 36 deletions
7
build-debug.sh
Executable file
7
build-debug.sh
Executable file
|
@ -0,0 +1,7 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# pnpm run clean-all
|
||||||
|
|
||||||
|
pnpm install --frozen-lockfile
|
||||||
|
pnpm run build:debug
|
||||||
|
|
||||||
|
pnpm run migrate
|
52
dev/macos/README.md
Normal file
52
dev/macos/README.md
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
## macOS installation methods
|
||||||
|
|
||||||
|
- install redis and postgresql
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./install.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
- build pgroonga
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./build-pgroonga.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
- start redis and postgresql
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./start-postgres.sh
|
||||||
|
|
||||||
|
# and
|
||||||
|
./start-redis.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
- setup detabase
|
||||||
|
|
||||||
|
* create db and user
|
||||||
|
|
||||||
|
```bash
|
||||||
|
psql -d postgres -U $USER
|
||||||
|
```
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Create a new PostgreSQL user named 'firefish' with encrypted password.
|
||||||
|
-- This user will not have superuser, createdb, or createrole privileges.
|
||||||
|
CREATE USER firefish WITH ENCRYPTED PASSWORD 'password' SUPERUSER NOCREATEDB NOCREATEROLE;
|
||||||
|
|
||||||
|
-- Create a new database named 'firefish_db' with UTF8 encoding and owned by the 'firefish' user.
|
||||||
|
CREATE DATABASE firefish_db WITH ENCODING 'UTF8' OWNER firefish;
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
- enable pgroonga extension
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# enter this command then type password
|
||||||
|
psql -U firefish -d firefish_db -W
|
||||||
|
```
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- This ensures the PGroonga extension is enabled for the database.
|
||||||
|
CREATE EXTENSION pgroonga;
|
||||||
|
```
|
8
dev/macos/build-pgroonga.sh
Executable file
8
dev/macos/build-pgroonga.sh
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
sudo -v
|
||||||
|
brew install groonga
|
||||||
|
|
||||||
|
git clone --recursive https://github.com/pgroonga/pgroonga.git --depth 1
|
||||||
|
cd pgroonga
|
||||||
|
make
|
||||||
|
sudo make install
|
3
dev/macos/install.sh
Executable file
3
dev/macos/install.sh
Executable file
|
@ -0,0 +1,3 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
brew install redis
|
||||||
|
brew install postgresql@16
|
9
dev/macos/start-postgres.sh
Executable file
9
dev/macos/start-postgres.sh
Executable file
|
@ -0,0 +1,9 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
export PATH="/opt/homebrew/opt/postgresql@16/bin:$PATH"
|
||||||
|
|
||||||
|
export LDFLAGS="-L/opt/homebrew/opt/postgresql@16/lib"
|
||||||
|
export CPPFLAGS="-I/opt/homebrew/opt/postgresql@16/include"
|
||||||
|
export PKG_CONFIG_PATH="/opt/homebrew/opt/postgresql@16/lib/pkgconfig"
|
||||||
|
|
||||||
|
LC_ALL="C" /opt/homebrew/opt/postgresql@16/bin/postgres -D /opt/homebrew/var/postgresql@16
|
2
dev/macos/start-redis.sh
Executable file
2
dev/macos/start-redis.sh
Executable file
|
@ -0,0 +1,2 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
redis-server
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "puyoskey",
|
"name": "puyoskey",
|
||||||
"version": "v0.1.2-20240818.snapshot-16d0df49724a614ee912c022d2540c8b7040805f",
|
"version": "0.1.4-20240818.snapshot-16d0df49724a614ee912c022d2540c8b7040805f",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.v-sli.me/HidemaruOwO/puyoskey.git"
|
"url": "https://git.v-sli.me/HidemaruOwO/puyoskey.git"
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
:style="bg"
|
:style="bg"
|
||||||
>
|
>
|
||||||
<img class="icon" :src="getInstanceIcon(instance)" @error="getInstanceIconErrorEvent($event)" aria-hidden="true" />
|
<img class="icon" :src="getInstanceIcon(instance)" @error="getInstanceIconErrorEvent($event)" aria-hidden="true" />
|
||||||
<span class="name">{{ instance.name }}</span>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -267,7 +267,7 @@ onMounted(() => {
|
||||||
await document.fonts.ready;
|
await document.fonts.ready;
|
||||||
if (props.tab == null) return;
|
if (props.tab == null) return;
|
||||||
if (!isTabs(props.tabs)) return;
|
if (!isTabs(props.tabs)) return;
|
||||||
if (props.tab === "home") {
|
if (props.tab === "home" && location.pathname === "/") {
|
||||||
emit("update:tab", "social");
|
emit("update:tab", "social");
|
||||||
}
|
}
|
||||||
const tabEl = tabRefs[props.tab];
|
const tabEl = tabRefs[props.tab];
|
||||||
|
|
|
@ -136,7 +136,7 @@ function checkForSplash() {
|
||||||
"yi",
|
"yi",
|
||||||
].includes((lang ?? "en").split("-")[0])
|
].includes((lang ?? "en").split("-")[0])
|
||||||
? "rtl"
|
? "rtl"
|
||||||
: "ltr",
|
: "ltr"
|
||||||
);
|
);
|
||||||
const writingMode = localStorage.getItem("writingMode");
|
const writingMode = localStorage.getItem("writingMode");
|
||||||
switch (writingMode) {
|
switch (writingMode) {
|
||||||
|
@ -224,7 +224,7 @@ function checkForSplash() {
|
||||||
? defineAsyncComponent(() => import("@/ui/visitor.vue"))
|
? defineAsyncComponent(() => import("@/ui/visitor.vue"))
|
||||||
: ui === "deck"
|
: ui === "deck"
|
||||||
? defineAsyncComponent(() => import("@/ui/deck.vue"))
|
? defineAsyncComponent(() => import("@/ui/deck.vue"))
|
||||||
: defineAsyncComponent(() => import("@/ui/universal.vue")),
|
: defineAsyncComponent(() => import("@/ui/universal.vue"))
|
||||||
);
|
);
|
||||||
|
|
||||||
if (_DEV_) {
|
if (_DEV_) {
|
||||||
|
@ -282,10 +282,12 @@ function checkForSplash() {
|
||||||
// ログインしてる場合だけ
|
// ログインしてる場合だけ
|
||||||
if (me) {
|
if (me) {
|
||||||
popup(
|
popup(
|
||||||
defineAsyncComponent(() => import("@/components/MkUpdated.vue")),
|
defineAsyncComponent(
|
||||||
|
() => import("@/components/MkUpdated.vue")
|
||||||
|
),
|
||||||
{},
|
{},
|
||||||
{},
|
{},
|
||||||
"closed",
|
"closed"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -294,7 +296,9 @@ function checkForSplash() {
|
||||||
if (
|
if (
|
||||||
isSignedIn(me) &&
|
isSignedIn(me) &&
|
||||||
defaultStore.state.tutorial === -1 &&
|
defaultStore.state.tutorial === -1 &&
|
||||||
!["/announcements", "/announcements/"].includes(window.location.pathname)
|
!["/announcements", "/announcements/"].includes(
|
||||||
|
window.location.pathname
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
api("announcements", { withUnreads: true, limit: 10 })
|
api("announcements", { withUnreads: true, limit: 10 })
|
||||||
.then((announcements) => {
|
.then((announcements) => {
|
||||||
|
@ -304,22 +308,25 @@ function checkForSplash() {
|
||||||
if (unreadAnnouncements.length > 3) {
|
if (unreadAnnouncements.length > 3) {
|
||||||
popup(
|
popup(
|
||||||
defineAsyncComponent(
|
defineAsyncComponent(
|
||||||
() => import("@/components/MkManyAnnouncements.vue"),
|
() => import("@/components/MkManyAnnouncements.vue")
|
||||||
),
|
),
|
||||||
{},
|
{},
|
||||||
{},
|
{},
|
||||||
"closed",
|
"closed"
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
for (const item of unreadAnnouncements) {
|
for (const item of unreadAnnouncements) {
|
||||||
if (item.showPopup)
|
if (item.showPopup)
|
||||||
popup(
|
popup(
|
||||||
defineAsyncComponent(
|
defineAsyncComponent(
|
||||||
() => import("@/components/MkAnnouncement.vue"),
|
() =>
|
||||||
|
import(
|
||||||
|
"@/components/MkAnnouncement.vue"
|
||||||
|
)
|
||||||
),
|
),
|
||||||
{ announcement: item },
|
{ announcement: item },
|
||||||
{},
|
{},
|
||||||
"closed",
|
"closed"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -334,14 +341,16 @@ function checkForSplash() {
|
||||||
applyTheme(
|
applyTheme(
|
||||||
darkMode
|
darkMode
|
||||||
? ColdDeviceStorage.get("darkTheme")
|
? ColdDeviceStorage.get("darkTheme")
|
||||||
: ColdDeviceStorage.get("lightTheme"),
|
: ColdDeviceStorage.get("lightTheme")
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
{ immediate: localStorage.theme == null },
|
{ immediate: localStorage.theme == null }
|
||||||
);
|
);
|
||||||
|
|
||||||
const darkTheme = computed(ColdDeviceStorage.makeGetterSetter("darkTheme"));
|
const darkTheme = computed(ColdDeviceStorage.makeGetterSetter("darkTheme"));
|
||||||
const lightTheme = computed(ColdDeviceStorage.makeGetterSetter("lightTheme"));
|
const lightTheme = computed(
|
||||||
|
ColdDeviceStorage.makeGetterSetter("lightTheme")
|
||||||
|
);
|
||||||
|
|
||||||
watch(darkTheme, (theme) => {
|
watch(darkTheme, (theme) => {
|
||||||
if (defaultStore.state.darkMode) {
|
if (defaultStore.state.darkMode) {
|
||||||
|
@ -381,10 +390,10 @@ function checkForSplash() {
|
||||||
(v) => {
|
(v) => {
|
||||||
document.documentElement.style.setProperty(
|
document.documentElement.style.setProperty(
|
||||||
"--modalBgFilter",
|
"--modalBgFilter",
|
||||||
v ? "blur(4px)" : "none",
|
v ? "blur(4px)" : "none"
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
{ immediate: true },
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
|
@ -396,7 +405,7 @@ function checkForSplash() {
|
||||||
document.documentElement.style.setProperty("--blur", "none");
|
document.documentElement.style.setProperty("--blur", "none");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true },
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
let reloadDialogShowing = false;
|
let reloadDialogShowing = false;
|
||||||
|
@ -427,7 +436,7 @@ function checkForSplash() {
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const plugin of ColdDeviceStorage.get("plugins").filter(
|
for (const plugin of ColdDeviceStorage.get("plugins").filter(
|
||||||
(p) => p.active,
|
(p) => p.active
|
||||||
)) {
|
)) {
|
||||||
import("./plugin").then(({ install }) => {
|
import("./plugin").then(({ install }) => {
|
||||||
install(plugin);
|
install(plugin);
|
||||||
|
@ -460,19 +469,22 @@ function checkForSplash() {
|
||||||
toast(
|
toast(
|
||||||
i18n.t("welcomeBackWithName", {
|
i18n.t("welcomeBackWithName", {
|
||||||
name: me.name || me.username,
|
name: me.name || me.username,
|
||||||
}),
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
localStorage.setItem("lastUsed", Date.now().toString());
|
localStorage.setItem("lastUsed", Date.now().toString());
|
||||||
|
|
||||||
const latestDonationInfoShownAt = localStorage.getItem(
|
const latestDonationInfoShownAt = localStorage.getItem(
|
||||||
"latestDonationInfoShownAt",
|
"latestDonationInfoShownAt"
|
||||||
|
);
|
||||||
|
const neverShowDonationInfo = localStorage.getItem(
|
||||||
|
"neverShowDonationInfo"
|
||||||
);
|
);
|
||||||
const neverShowDonationInfo = localStorage.getItem("neverShowDonationInfo");
|
|
||||||
if (
|
if (
|
||||||
neverShowDonationInfo !== "true" &&
|
neverShowDonationInfo !== "true" &&
|
||||||
new Date(me.createdAt).getTime() < Date.now() - 1000 * 60 * 60 * 24 * 3 &&
|
new Date(me.createdAt).getTime() <
|
||||||
|
Date.now() - 1000 * 60 * 60 * 24 * 3 &&
|
||||||
!location.pathname.startsWith("/miauth")
|
!location.pathname.startsWith("/miauth")
|
||||||
) {
|
) {
|
||||||
if (
|
if (
|
||||||
|
@ -481,10 +493,12 @@ function checkForSplash() {
|
||||||
Date.now() - 1000 * 60 * 60 * 24 * 30
|
Date.now() - 1000 * 60 * 60 * 24 * 30
|
||||||
) {
|
) {
|
||||||
popup(
|
popup(
|
||||||
defineAsyncComponent(() => import("@/components/MkDonation.vue")),
|
defineAsyncComponent(
|
||||||
|
() => import("@/components/MkDonation.vue")
|
||||||
|
),
|
||||||
{},
|
{},
|
||||||
{},
|
{},
|
||||||
"closed",
|
"closed"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,9 +196,7 @@ async function chooseAntenna(ev: MouseEvent) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveSrc(
|
function saveSrc(newSrc: "social" | "local" | "global"): void {
|
||||||
newSrc: "home" | "local" | "social" | "recommended" | "global",
|
|
||||||
): void {
|
|
||||||
defaultStore.set("tl", {
|
defaultStore.set("tl", {
|
||||||
...defaultStore.state.tl,
|
...defaultStore.state.tl,
|
||||||
src: newSrc,
|
src: newSrc,
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onBeforeUnmount, onMounted, ref } from "vue";
|
import { onBeforeUnmount, onMounted, ref } from "vue";
|
||||||
import XPie from "./pie.vue";
|
import XPie from "./pie-large.vue";
|
||||||
import icon from "@/scripts/icon";
|
import icon from "@/scripts/icon";
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed } from "vue";
|
import { computed } from "vue";
|
||||||
|
|
||||||
import XPie from "./pie.vue";
|
import XPie from "./pie-large.vue";
|
||||||
import bytes from "@/filters/bytes";
|
import bytes from "@/filters/bytes";
|
||||||
import icon from "@/scripts/icon";
|
import icon from "@/scripts/icon";
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,21 @@
|
||||||
:connection="connection"
|
:connection="connection"
|
||||||
:meta="meta"
|
:meta="meta"
|
||||||
/>
|
/>
|
||||||
|
<XCpu
|
||||||
|
v-else-if="widgetProps.view === 1"
|
||||||
|
:connection="connection"
|
||||||
|
:meta="meta"
|
||||||
|
/>
|
||||||
|
<XMemory
|
||||||
|
v-else-if="widgetProps.view === 2"
|
||||||
|
:connection="connection"
|
||||||
|
:meta="meta"
|
||||||
|
/>
|
||||||
|
<XDisk
|
||||||
|
v-else-if="widgetProps.view === 3"
|
||||||
|
:connection="connection"
|
||||||
|
:meta="meta"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</MkContainer>
|
</MkContainer>
|
||||||
</template>
|
</template>
|
||||||
|
@ -38,6 +53,9 @@ import type {
|
||||||
WidgetComponentProps,
|
WidgetComponentProps,
|
||||||
} from "../widget";
|
} from "../widget";
|
||||||
import { useWidgetPropsManager } from "../widget";
|
import { useWidgetPropsManager } from "../widget";
|
||||||
|
import XCpu from "./cpu.vue";
|
||||||
|
import XMemory from "./mem.vue";
|
||||||
|
import XDisk from "./disk.vue";
|
||||||
import XCpuMemory from "./cpu-mem.vue";
|
import XCpuMemory from "./cpu-mem.vue";
|
||||||
import MkContainer from "@/components/MkContainer.vue";
|
import MkContainer from "@/components/MkContainer.vue";
|
||||||
import type { GetFormResultType } from "@/scripts/form";
|
import type { GetFormResultType } from "@/scripts/form";
|
||||||
|
@ -85,7 +103,7 @@ os.apiGet("server-info", {}).then((res) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const toggleView = () => {
|
const toggleView = () => {
|
||||||
widgetProps.view = (widgetProps.view + 1) % 1;
|
widgetProps.view = (widgetProps.view + 1) % 4;
|
||||||
save();
|
save();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onBeforeUnmount, onMounted, ref } from "vue";
|
import { onBeforeUnmount, onMounted, ref } from "vue";
|
||||||
import XPie from "./pie.vue";
|
import XPie from "./pie-large.vue";
|
||||||
import bytes from "@/filters/bytes";
|
import bytes from "@/filters/bytes";
|
||||||
import icon from "@/scripts/icon";
|
import icon from "@/scripts/icon";
|
||||||
|
|
||||||
|
|
62
packages/client/src/widgets/server-metric/pie-large.vue
Normal file
62
packages/client/src/widgets/server-metric/pie-large.vue
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
<!--
|
||||||
|
SPDX-FileCopyrightText: syuilo and misskey-project
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<svg :class="$style.root" viewBox="0 0 1 1" preserveAspectRatio="none">
|
||||||
|
<circle
|
||||||
|
:r="r"
|
||||||
|
cx="50%" cy="50%"
|
||||||
|
fill="none"
|
||||||
|
stroke-width="0.1"
|
||||||
|
stroke="rgba(0, 0, 0, 0.05)"
|
||||||
|
:class="$style.circle"
|
||||||
|
/>
|
||||||
|
<circle
|
||||||
|
:r="r"
|
||||||
|
cx="50%" cy="50%"
|
||||||
|
:stroke-dasharray="Math.PI * (r * 2)"
|
||||||
|
:stroke-dashoffset="strokeDashoffset"
|
||||||
|
fill="none"
|
||||||
|
stroke-width="0.1"
|
||||||
|
:class="$style.circle"
|
||||||
|
:stroke="color"
|
||||||
|
/>
|
||||||
|
<text x="50%" y="50%" dy="0.05" text-anchor="middle" :class="$style.text">{{ (value * 100).toFixed(0) }}%</text>
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed } from "vue";
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
value: number;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const r = 0.45;
|
||||||
|
|
||||||
|
const color = computed(() => `hsl(${180 - props.value * 180}, 80%, 70%)`);
|
||||||
|
const strokeDashoffset = computed(
|
||||||
|
() => (1 - props.value) * (Math.PI * (r * 2)),
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" module>
|
||||||
|
.root {
|
||||||
|
display: block;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circle {
|
||||||
|
transform-origin: center;
|
||||||
|
transform: rotate(-90deg);
|
||||||
|
transition: stroke-dashoffset 0.5s ease;
|
||||||
|
stroke-linecap: round;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
font-size: 0.15px;
|
||||||
|
fill: currentColor;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -57,7 +57,7 @@ export default defineConfig(({ command, mode }) => {
|
||||||
_DATA_TRANSFER_DRIVE_FOLDER_: JSON.stringify("mk_drive_folder"),
|
_DATA_TRANSFER_DRIVE_FOLDER_: JSON.stringify("mk_drive_folder"),
|
||||||
_DATA_TRANSFER_DECK_COLUMN_: JSON.stringify("mk_deck_column"),
|
_DATA_TRANSFER_DECK_COLUMN_: JSON.stringify("mk_deck_column"),
|
||||||
__VUE_OPTIONS_API__: true,
|
__VUE_OPTIONS_API__: true,
|
||||||
__VUE_PROD_DEVTOOLS__: false,
|
__VUE_PROD_DEVTOOLS__: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
build: {
|
build: {
|
||||||
|
|
Reference in a new issue