Compare commits

...

9 commits

17 changed files with 208 additions and 36 deletions

7
build-debug.sh Executable file
View 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
View 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
View 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
View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
brew install redis
brew install postgresql@16

9
dev/macos/start-postgres.sh Executable file
View 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
View file

@ -0,0 +1,2 @@
#!/usr/bin/env bash
redis-server

View file

@ -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"

View file

@ -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>

View file

@ -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];

View file

@ -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"
); );
} }
} }

View file

@ -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,

View file

@ -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<{

View file

@ -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";

View file

@ -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();
}; };

View file

@ -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";

View 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>

View file

@ -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: {