mirror of
https://git.boykissers.com/pawkey/pawkey-sk.git
synced 2025-12-20 04:04:16 +00:00
feat: [frontend / backend] update git urls, update userid watermark, authenticate image proxy and url previews
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<!-- 💖 Thanks for taking the time to fill out this bug report!
|
||||
💁 Having trouble with deployment? [Ask the support chat.]()
|
||||
🔒 Found a security vulnerability? [Please disclose it responsibly.](https://git.leafus.net/pawkey/pawkey/-/blob/stable/SECURITY.md)
|
||||
🤝 By submitting this feature request, you agree to follow our [Contribution Guidelines.](https://git.leafus.net/pawkey/pawkey/-/blob/stable/CONTRIBUTING.md) -->
|
||||
🔒 Found a security vulnerability? [Please disclose it responsibly.](https://git.pawlickers.org/pawkey/pawkey/src/branch/stable/SECURITY.md)
|
||||
🤝 By submitting this feature request, you agree to follow our [Contribution Guidelines.](https://git.pawlickers.org/pawkey/pawkey/src/branch/stable/CONTRIBUTING.md) -->
|
||||
|
||||
# **What happened?**
|
||||
<!-- Please give us a brief description of what happened. -->
|
||||
@@ -30,6 +30,6 @@
|
||||
<!-- Please copy and paste any relevant log output. You can find your log by inspecting the page, and going to the "console" tab. This will be automatically formatted into code, so no need for backticks. -->
|
||||
|
||||
# **Contribution Guidelines**
|
||||
By submitting this issue, you agree to follow our [Contribution Guidelines](https://git.leafus.net/pawkey/pawkey/-/blob/stable/CONTRIBUTING.md)
|
||||
By submitting this issue, you agree to follow our [Contribution Guidelines](https://git.pawlickers.org/pawkey/pawkey/src/branch/stable/CONTRIBUTING.md)
|
||||
- [ ] I agree to follow this project's Contribution Guidelines
|
||||
- [ ] I have searched the issue tracker for similar issues, and this is not a duplicate.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!-- 💖 Thanks for taking the time to fill out this bug report!
|
||||
💁 Having trouble with deployment? [Ask the support chat.]()
|
||||
🔒 Found a security vulnerability? [Please disclose it responsibly.](https://git.leafus.net/pawkey/pawkey/-/blob/stable/SECURITY.md)
|
||||
🤝 By submitting this feature request, you agree to follow our [Contribution Guidelines.](https://git.leafus.net/pawkey/pawkey/-/blob/stable/CONTRIBUTING.md) -->
|
||||
🔒 Found a security vulnerability? [Please disclose it responsibly.](https://git.pawlickers.org/pawkey/pawkey/src/branch/stable/SECURITY.md)
|
||||
🤝 By submitting this feature request, you agree to follow our [Contribution Guidelines.](https://git.pawlickers.org/pawkey/pawkey/src/branch/stable/CONTRIBUTING.md) -->
|
||||
|
||||
# **What feature would you like implemented?**
|
||||
<!-- Please give us a brief description of what you'd like. -->
|
||||
@@ -16,6 +16,6 @@
|
||||
<!-- What instance of Pawkey are you using? -->
|
||||
|
||||
# **Contribution Guidelines**
|
||||
By submitting this issue, you agree to follow our [Contribution Guidelines](https://activitypub.software/TransFem-org/Pawkey/-/blob/develop/CONTRIBUTING.md)
|
||||
By submitting this issue, you agree to follow our [Contribution Guidelines](https://git.pawlickers.org/pawkey/pawkey/src/branch/stable/CONTRIBUTING.md)
|
||||
- [ ] I agree to follow this project's Contribution Guidelines
|
||||
- [ ] I have searched the issue tracker for similar requests, and this is not a duplicate.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
%{all_commits}
|
||||
|
||||
# **Contribution Guidelines**
|
||||
By submitting this merge request, you agree to follow our [Contribution Guidelines](https://git.leafus.net/pawkey/pawkey/-/blob/stable/CONTRIBUTING.md)
|
||||
By submitting this merge request, you agree to follow our [Contribution Guidelines](https://git.pawlickers.org/pawkey/pawkey/src/branch/stable/CONTRIBUTING.md)
|
||||
- [ ] I agree to follow this project's Contribution Guidelines
|
||||
- [ ] I have made sure to test this merge request
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ An actual domain will be assigned so you can test the federation.
|
||||
- `x.y.z` is the new version you are trying to release.
|
||||
3. Deploy and perform a simple QA check. Also verify that the tests passed.
|
||||
4. Merge it. (Do not squash commit)
|
||||
5. Create a [release](https://git.leafus.net/pawkey/pawkey/-/releases)
|
||||
5. Create a [release](https://git.pawlickers.org/pawkey/pawkey/releases)
|
||||
- The target branch must be `stable`
|
||||
- The tag name must be the version
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<div align="center">
|
||||
<a href="https://pawkey.dev">
|
||||
<img src="https://git.leafus.net/pawkey/pawkey/-/raw/stable/packages/frontend/assets/pawkey.png" alt="Pawkey logo" width="300"/>
|
||||
<img src="https://git.pawlickers.org/pawkey/pawkey/raw/branch/stable/packages/frontend/assets/pawkey.png" alt="Pawkey logo" width="300"/>
|
||||
</a>
|
||||
|
||||
**🌎 **[Pawkey](https://pawkey.dev)** is an open source, decentralized social media platform that's free forever! 🚀**
|
||||
|
||||
2
locales/index.d.ts
vendored
2
locales/index.d.ts
vendored
@@ -4888,7 +4888,7 @@ export interface Locale extends ILocale {
|
||||
*/
|
||||
"repositoryUrl": string;
|
||||
/**
|
||||
* If there is a repository where the source code is publicly available, enter its URL. If you are using Pawkey as-is (without any changes to the source code), enter https://git.leafus.net/pawkey/pawkey.
|
||||
* If there is a repository where the source code is publicly available, enter its URL. If you are using Pawkey as-is (without any changes to the source code), enter https://git.pawlickers.org/pawkey/pawkey.
|
||||
*/
|
||||
"repositoryUrlDescription": string;
|
||||
/**
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"codename": "pawjob",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.leafus.net/pawkey/pawkey.git"
|
||||
"url": "https://git.pawlickers.org/pawkey/pawkey.git"
|
||||
},
|
||||
"packageManager": "pnpm@9.6.0",
|
||||
"workspaces": [
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
export class AddSomeUrls1557761316509 {
|
||||
async up(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "ToSUrl" character varying(512)`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "repositoryUrl" character varying(512) NOT NULL DEFAULT 'https://git.leafus.net/pawkey/pawkey'`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "feedbackUrl" character varying(512) DEFAULT 'https://git.leafus.net/pawkey/pawkey/issues/new/choose'`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "repositoryUrl" character varying(512) NOT NULL DEFAULT 'https://git.pawlickers.org/pawkey/pawkey'`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "feedbackUrl" character varying(512) DEFAULT 'https://git.pawlickers.org/pawkey/pawkey/issues/new'`);
|
||||
}
|
||||
async down(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "feedbackUrl"`);
|
||||
|
||||
22
packages/backend/migration/1763436210524-ChangeGITUrls.js
Normal file
22
packages/backend/migration/1763436210524-ChangeGITUrls.js
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: pawinput and Pawkey contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export class ChangeGITUrls1763436210524 {
|
||||
name = 'ChangeGITUrls1763436210524'
|
||||
|
||||
async up(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "repositoryUrl" SET DEFAULT 'https://git.pawlickers.org/pawkey/pawkey'`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "feedbackUrl" SET DEFAULT 'https://git.pawlickers.org/pawkey/pawkey/issues/new'`);
|
||||
await queryRunner.query(`UPDATE "meta" SET "repositoryUrl"=DEFAULT WHERE "repositoryUrl" IN ('https://git.leafus.net/pawkey/pawkey')`);
|
||||
await queryRunner.query(`UPDATE "meta" SET "feedbackUrl"=DEFAULT WHERE "feedbackUrl" IN ('https://git.leafus.net/pawkey/pawkey/-/issues/new')`);
|
||||
}
|
||||
|
||||
async down(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "repositoryUrl" SET DEFAULT 'https://git.leafus.net/pawkey/pawkey'`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "feedbackUrl" SET DEFAULT 'https://git.leafus.net/pawkey/pawkey/-/issues/new'`);
|
||||
await queryRunner.query(`UPDATE "meta" SET "repositoryUrl"=DEFAULT WHERE "repositoryUrl" IN ('https://git.pawlickers.org/pawkey/pawkey')`);
|
||||
await queryRunner.query(`UPDATE "meta" SET "feedbackUrl"=DEFAULT WHERE "feedbackUrl" IN ('https://git.pawlickers.org/pawkey/pawkey/issues/new')`);
|
||||
}
|
||||
}
|
||||
@@ -483,7 +483,7 @@ export function loadConfig(): Config {
|
||||
videoThumbnailGenerator: config.videoThumbnailGenerator ?
|
||||
config.videoThumbnailGenerator.endsWith('/') ? config.videoThumbnailGenerator.substring(0, config.videoThumbnailGenerator.length - 1) : config.videoThumbnailGenerator
|
||||
: null,
|
||||
userAgent: `Misskey/${version} (${config.url})`,
|
||||
userAgent: `Pawkey/${version} (${config.url})`,
|
||||
frontendEntry: frontendManifest['src/_boot_.ts'],
|
||||
frontendManifestExists: frontendManifestExists,
|
||||
frontendEmbedEntry: frontendEmbedManifest['src/boot.ts'],
|
||||
|
||||
@@ -458,14 +458,14 @@ export class MiMeta {
|
||||
|
||||
@Column('varchar', {
|
||||
length: 1024,
|
||||
default: 'https://git.leafus.net/pawkey/pawkey/',
|
||||
default: 'https://git.pawlickers.org/pawkey/pawkey/',
|
||||
nullable: false,
|
||||
})
|
||||
public repositoryUrl: string | null;
|
||||
|
||||
@Column('varchar', {
|
||||
length: 1024,
|
||||
default: 'https://git.leafus.net/pawkey/pawkey/-/issues/new',
|
||||
default: 'https://git.pawlickers.org/pawkey/pawkey/issues/new',
|
||||
nullable: true,
|
||||
})
|
||||
public feedbackUrl: string | null;
|
||||
|
||||
@@ -108,6 +108,43 @@ export class FileServerService {
|
||||
return;
|
||||
}
|
||||
|
||||
const body = request.method === 'GET'
|
||||
? request.query
|
||||
: request.body;
|
||||
|
||||
let cookieToken: string | undefined;
|
||||
if (request.headers.cookie) {
|
||||
const cookies = request.headers.cookie.split(';').reduce((acc, cookie) => {
|
||||
const [key, value] = cookie.trim().split('=');
|
||||
acc[key] = value;
|
||||
return acc;
|
||||
}, {} as Record<string, string>);
|
||||
cookieToken = cookies.token;
|
||||
}
|
||||
|
||||
const token = request.headers.authorization?.startsWith('Bearer ')
|
||||
? request.headers.authorization.slice(7)
|
||||
: (body as any)?.['i'] ?? cookieToken;
|
||||
|
||||
if (token != null && typeof token !== 'string') {
|
||||
reply.code(400);
|
||||
return;
|
||||
}
|
||||
|
||||
const [user] = await this.authenticateService.authenticate(token);
|
||||
|
||||
if (!user) {
|
||||
reply.code(401);
|
||||
reply.send({
|
||||
error: {
|
||||
message: 'Credential required.',
|
||||
code: 'CREDENTIAL_REQUIRED',
|
||||
id: '1384574d-a912-4b81-8601-c7b1c4085df1',
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const keyUrl = new URL(url);
|
||||
keyUrl.searchParams.forEach(k => keyUrl.searchParams.delete(k));
|
||||
keyUrl.hash = '';
|
||||
@@ -632,7 +669,7 @@ export class FileServerService {
|
||||
// https://datatracker.ietf.org/doc/html/rfc6750.html#section-2.1 (case sensitive)
|
||||
const token = request.headers.authorization?.startsWith('Bearer ')
|
||||
? request.headers.authorization.slice(7)
|
||||
: body?.['i'];
|
||||
: (body as any)?.['i'];
|
||||
if (token != null && typeof token !== 'string') {
|
||||
reply.code(400);
|
||||
return false;
|
||||
|
||||
@@ -95,12 +95,27 @@ export class StreamingApiServerService {
|
||||
? request.headers.authorization.slice(7)
|
||||
: q.get('i');
|
||||
|
||||
// Require authentication for WebSocket connections
|
||||
if (!token) {
|
||||
socket.write([
|
||||
'HTTP/1.1 401 Unauthorized',
|
||||
'WWW-Authenticate: Bearer realm="Misskey"',
|
||||
].join('\r\n') + '\r\n\r\n');
|
||||
socket.destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
[user, app] = await this.authenticateService.authenticate(token);
|
||||
|
||||
if (app !== null && !app.permission.some(p => p === 'read:account')) {
|
||||
throw new AuthenticationError('Your app does not have necessary permissions to use websocket API.');
|
||||
}
|
||||
|
||||
// Ensure we have a valid user
|
||||
if (!user) {
|
||||
throw new AuthenticationError('Invalid token or user not found.');
|
||||
}
|
||||
} catch (e) {
|
||||
if (e instanceof AuthenticationError) {
|
||||
socket.write([
|
||||
|
||||
@@ -19,7 +19,7 @@ export function genOpenapiSpec(config: Config, includeSelfRef = false) {
|
||||
|
||||
externalDocs: {
|
||||
description: 'Repository',
|
||||
url: 'https://git.leafus.net/pawkey/pawkey',
|
||||
url: 'https://git.pawlickers.org/pawkey/pawkey',
|
||||
},
|
||||
|
||||
servers: [{
|
||||
@@ -97,7 +97,7 @@ export function genOpenapiSpec(config: Config, includeSelfRef = false) {
|
||||
description: desc,
|
||||
externalDocs: {
|
||||
description: 'Source code',
|
||||
url: `https://git.leafus.net/pawkey/pawkey/-/tree/stable/packages/backend/src/server/api/endpoints/${endpoint.name}.ts`,
|
||||
url: `https://git.pawlickers.org/pawkey/pawkey/src/branch/stable/packages/backend/src/server/api/endpoints/${endpoint.name}.ts`,
|
||||
},
|
||||
...(endpoint.meta.tags ? {
|
||||
tags: [endpoint.meta.tags[0]],
|
||||
|
||||
@@ -169,8 +169,22 @@ export class UrlPreviewService {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check rate limit
|
||||
// Check authentication
|
||||
const auth = await this.authenticate(request);
|
||||
const [user] = auth;
|
||||
|
||||
if (!user) {
|
||||
reply.code(401);
|
||||
return reply.send({
|
||||
error: {
|
||||
message: 'Credential required.',
|
||||
code: 'CREDENTIAL_REQUIRED',
|
||||
id: '1384574d-a912-4b81-8601-c7b1c4085df1',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// Check rate limit
|
||||
if (!await this.checkRateLimit(auth, reply)) {
|
||||
return;
|
||||
}
|
||||
@@ -450,10 +464,21 @@ export class UrlPreviewService {
|
||||
private async authenticate(request: FastifyRequest<{ Querystring?: { i?: string | string[] }, Body?: { i?: string | string[] } }>): Promise<AuthArray> {
|
||||
const body = request.method === 'GET' ? request.query : request.body;
|
||||
|
||||
// Parse token from cookie header if present
|
||||
let cookieToken: string | undefined;
|
||||
if (request.headers.cookie) {
|
||||
const cookies = request.headers.cookie.split(';').reduce((acc, cookie) => {
|
||||
const [key, value] = cookie.trim().split('=');
|
||||
acc[key] = value;
|
||||
return acc;
|
||||
}, {} as Record<string, string>);
|
||||
cookieToken = cookies.token;
|
||||
}
|
||||
|
||||
// https://datatracker.ietf.org/doc/html/rfc6750.html#section-2.1 (case sensitive)
|
||||
const token = request.headers.authorization?.startsWith('Bearer ')
|
||||
? request.headers.authorization.slice(7)
|
||||
: body?.['i'];
|
||||
: body?.['i'] ?? cookieToken;
|
||||
if (token != null && typeof token !== 'string') {
|
||||
return [undefined, undefined, getIpHash(request.ip)];
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 382 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 223 KiB After Width: | Height: | Size: 774 KiB |
@@ -16,6 +16,7 @@ import { prefer } from '@/preferences.js';
|
||||
import { store } from '@/store.js';
|
||||
import { $i } from '@/i.js';
|
||||
import { signout } from '@/signout.js';
|
||||
import Cookies from 'js-cookie';
|
||||
|
||||
type AccountWithToken = Misskey.entities.MeDetailed & { token: string };
|
||||
|
||||
@@ -186,6 +187,8 @@ export async function login(token: AccountWithToken['token'], redirect?: string)
|
||||
token,
|
||||
}));
|
||||
|
||||
Cookies.set('token', token, { expires: 365 * 100 });
|
||||
|
||||
await addAccount(host, me, token);
|
||||
|
||||
if (redirect) {
|
||||
|
||||
@@ -335,7 +335,7 @@ export async function mainBoot() {
|
||||
}
|
||||
|
||||
const modifiedVersionMustProminentlyOfferInAgplV3Section13Read = miLocalStorage.getItem('modifiedVersionMustProminentlyOfferInAgplV3Section13Read');
|
||||
if (modifiedVersionMustProminentlyOfferInAgplV3Section13Read !== 'true' && instance.repositoryUrl !== 'https://git.leafus.net/pawkey/pawkey') {
|
||||
if (modifiedVersionMustProminentlyOfferInAgplV3Section13Read !== 'true' && instance.repositoryUrl !== 'https://git.pawlickers.org/pawkey/pawkey') {
|
||||
const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkSourceCodeAvailablePopup.vue')), {}, {
|
||||
closed: () => dispose(),
|
||||
});
|
||||
|
||||
@@ -47,7 +47,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<template #label>{{ i18n.ts.basicNotesBeforeCreateAccount }}</template>
|
||||
<template #suffix><i v-if="agreeNote" class="ti ti-check" style="color: var(--MI_THEME-success)"></i></template>
|
||||
|
||||
<a href="https://git.leafus.net/pawkey/pawkey/-/blob/stable/IMPORTANT_NOTES.md" class="_link" target="_blank">{{ i18n.ts.basicNotesBeforeCreateAccount }} <i class="ti ti-external-link"></i></a>
|
||||
<a href="https://git.pawlickers.org/pawkey/pawkey/src/branch/stable/IMPORTANT_NOTES.md" class="_link" target="_blank">{{ i18n.ts.basicNotesBeforeCreateAccount }} <i class="ti ti-external-link"></i></a>
|
||||
|
||||
<MkSwitch :modelValue="agreeNote" style="margin-top: 16px;" data-cy-signup-rules-notes-agree @update:modelValue="updateAgreeNote">{{ i18n.ts.agree }}</MkSwitch>
|
||||
</MkFolder>
|
||||
|
||||
@@ -27,7 +27,7 @@ const modal = useTemplateRef('modal');
|
||||
|
||||
const whatIsNew = () => {
|
||||
modal.value?.close();
|
||||
window.open(`https://git.leafus.net/pawkey/pawkey/-/releases/${version}`, '_blank');
|
||||
window.open(`https://git.pawlickers.org/pawkey/pawkey/releases${version}`, '_blank');
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { $i } from "@/i.js";
|
||||
import { computed, onMounted, ref } from "vue";
|
||||
import { computed, onMounted, onUnmounted, ref } from "vue";
|
||||
|
||||
const generateRandomClass = () => {
|
||||
const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
@@ -14,10 +14,27 @@ const generateRandomClass = () => {
|
||||
const gridClass = ref(generateRandomClass());
|
||||
const itemClasses = ref<string[]>([]);
|
||||
const recreationKey = ref(0);
|
||||
const gridItemCount = ref(600);
|
||||
let regenerationInterval: ReturnType<typeof setInterval> | null = null;
|
||||
let styleElement: HTMLStyleElement | null = null;
|
||||
let allCreatedClasses: string[] = [];
|
||||
|
||||
// Calculate grid items based on screen resolution
|
||||
const calculateGridItemCount = () => {
|
||||
const width = window.innerWidth;
|
||||
const height = window.innerHeight;
|
||||
|
||||
// Grid cell size: 80px width + 10px gap, 16px height + 10px gap (more concise)
|
||||
const itemWidth = 80 + 10;
|
||||
const itemHeight = 16 + 10;
|
||||
|
||||
const columns = Math.ceil(width / itemWidth);
|
||||
const rows = Math.ceil(height / itemHeight);
|
||||
|
||||
// Add some buffer (20%) to ensure coverage during animations/scrolling
|
||||
return Math.ceil(columns * rows * 1.2);
|
||||
};
|
||||
|
||||
const encodeTextToPath = (text: string) => {
|
||||
const charPaths: { [key: string]: string } = {
|
||||
a: "M2,8 L4,2 L6,2 L8,8 M3,6 L7,6",
|
||||
@@ -77,7 +94,7 @@ const encodeTextToPath = (text: string) => {
|
||||
);
|
||||
path += translatedPath + " ";
|
||||
}
|
||||
xOffset += 10;
|
||||
xOffset += 7; // Reduced from 10 to 7 for tighter spacing
|
||||
});
|
||||
|
||||
return path.trim();
|
||||
@@ -95,7 +112,9 @@ const regenerateWatermark = () => {
|
||||
cleanupOldElements();
|
||||
|
||||
gridClass.value = generateRandomClass();
|
||||
itemClasses.value = generateItemClasses(600);
|
||||
const count = calculateGridItemCount();
|
||||
gridItemCount.value = count;
|
||||
itemClasses.value = generateItemClasses(count);
|
||||
recreationKey.value++;
|
||||
|
||||
allCreatedClasses.push(gridClass.value, ...itemClasses.value);
|
||||
@@ -140,13 +159,13 @@ const createStyleElement = () => {
|
||||
.${className} svg {
|
||||
opacity: 0.02 !important;
|
||||
width: auto !important;
|
||||
height: 12px !important;
|
||||
height: 10px !important;
|
||||
}
|
||||
|
||||
.${className} svg path {
|
||||
stroke: var(--MI_THEME-fg) !important;
|
||||
fill: none !important;
|
||||
stroke-width: 1 !important;
|
||||
stroke-width: 0.8 !important;
|
||||
}
|
||||
`,
|
||||
)
|
||||
@@ -160,10 +179,10 @@ const createStyleElement = () => {
|
||||
width: 100vw !important;
|
||||
height: 100vh !important;
|
||||
display: grid !important;
|
||||
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)) !important;
|
||||
grid-template-rows: repeat(auto-fill, minmax(20px, 1fr)) !important;
|
||||
gap: 20px !important;
|
||||
padding: 20px !important;
|
||||
grid-template-columns: repeat(auto-fill, minmax(80px, 1fr)) !important;
|
||||
grid-template-rows: repeat(auto-fill, minmax(16px, 1fr)) !important;
|
||||
gap: 10px !important;
|
||||
padding: 10px !important;
|
||||
pointer-events: none !important;
|
||||
z-index: 999999999 !important;
|
||||
overflow: hidden !important;
|
||||
@@ -177,24 +196,51 @@ const createStyleElement = () => {
|
||||
|
||||
const watermarkText = computed(() => $i?.id || "not signed in");
|
||||
const pathData = computed(() => encodeTextToPath(watermarkText.value));
|
||||
const textWidth = computed(() => watermarkText.value.length * 10 + 10);
|
||||
const textWidth = computed(() => watermarkText.value.length * 7 + 10); // Adjusted for tighter spacing
|
||||
|
||||
let resizeTimeout: ReturnType<typeof setTimeout> | null = null;
|
||||
|
||||
const handleResize = () => {
|
||||
if (resizeTimeout) clearTimeout(resizeTimeout);
|
||||
|
||||
// Debounce resize to avoid excessive recalculations
|
||||
resizeTimeout = setTimeout(() => {
|
||||
regenerateWatermark();
|
||||
}, 250);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
itemClasses.value = generateItemClasses(600);
|
||||
const count = calculateGridItemCount();
|
||||
gridItemCount.value = count;
|
||||
itemClasses.value = generateItemClasses(count);
|
||||
allCreatedClasses.push(gridClass.value, ...itemClasses.value);
|
||||
createStyleElement();
|
||||
|
||||
regenerationInterval = setInterval(() => {
|
||||
itemClasses.value = generateItemClasses(600);
|
||||
const count = calculateGridItemCount();
|
||||
gridItemCount.value = count;
|
||||
itemClasses.value = generateItemClasses(count);
|
||||
allCreatedClasses.push(gridClass.value, ...itemClasses.value);
|
||||
regenerateWatermark();
|
||||
}, 5000);
|
||||
|
||||
window.addEventListener("resize", handleResize);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
if (regenerationInterval) clearInterval(regenerationInterval);
|
||||
if (resizeTimeout) clearTimeout(resizeTimeout);
|
||||
window.removeEventListener("resize", handleResize);
|
||||
cleanupOldElements();
|
||||
if (styleElement && styleElement.parentNode) {
|
||||
styleElement.parentNode.removeChild(styleElement);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :key="`watermark-${recreationKey}`" :class="gridClass">
|
||||
<div v-for="n in 600" :key="n" :class="itemClasses[n]">
|
||||
<div v-for="n in gridItemCount" :key="n" :class="itemClasses[n]">
|
||||
<svg :viewBox="`0 0 ${textWidth} 10`" xmlns="http://www.w3.org/2000/svg">
|
||||
<path :d="pathData" />
|
||||
</svg>
|
||||
|
||||
@@ -22,12 +22,12 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<button v-if="thereIsTreasure" class="_button treasure" @click="getTreasure"><img src="/fluent-emoji/1f3c6.png" class="treasureImg"></button>
|
||||
</div>
|
||||
<div style="text-align: center;">
|
||||
{{ i18n.ts._aboutMisskey.about }}<br><a href="https://leafus.net/pawkey" target="_blank" class="_link">{{ i18n.ts.learnMore }}</a>
|
||||
{{ i18n.ts._aboutMisskey.about }}<br><a href="https://pawkey.dev" target="_blank" class="_link">{{ i18n.ts.learnMore }}</a>
|
||||
</div>
|
||||
<div v-if="$i != null" style="text-align: center;">
|
||||
<MkButton primary rounded inline @click="iLoveMisskey">I <Mfm text="$[jelly ❤]"/> #Pawkey</MkButton>
|
||||
</div>
|
||||
<FormSection v-if="instance.repositoryUrl !== 'https://git.leafus.net/pawkey/pawkey'">
|
||||
<FormSection v-if="instance.repositoryUrl !== 'https://git.pawlickers.org/pawkey/pawkey'">
|
||||
<div class="_gaps_s">
|
||||
<FormLink v-if="instance.repositoryUrl" :to="instance.repositoryUrl" external>
|
||||
<template #icon><i class="ti ti-code"></i></template>
|
||||
@@ -45,7 +45,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</FormSection>
|
||||
<FormSection>
|
||||
<div class="_gaps_s">
|
||||
<FormLink to="https://git.leafus.net/pawkey/pawkey" external>
|
||||
<FormLink to="https://git.pawlickers.org/pawkey/pawkey" external>
|
||||
<template #icon><i class="ph-code ph-bold ph-lg"></i></template>
|
||||
{{ i18n.ts._aboutMisskey.source }} ({{ i18n.ts._aboutMisskey.original_pawkey }})
|
||||
<template #suffix>GitLab</template>
|
||||
@@ -128,81 +128,12 @@ const everyone = ref<Section[]>([
|
||||
heading: 'Pawkey Creators',
|
||||
people: fisher_yates([
|
||||
{
|
||||
handle: '@Leafus',
|
||||
avatar: 'https://git.leafus.net/uploads/-/system/user/avatar/2/avatar.png?width=192',
|
||||
link: 'https://leafus.net',
|
||||
handle: '@pawinput',
|
||||
avatar: 'https://git.pawlickers.org/avatars/5e909e3e9e43b099242596d67debcd61264809b7765f160b01c8a376f23e47a5?size=512',
|
||||
link: 'https://pawlickers.org',
|
||||
},
|
||||
]),
|
||||
},
|
||||
{
|
||||
heading: 'Sharkey Contributors',
|
||||
link: {
|
||||
label: i18n.ts._aboutMisskey.allContributors,
|
||||
url: 'https://activitypub.software/TransFem-org/Sharkey/-/graphs/develop',
|
||||
},
|
||||
people: fisher_yates([
|
||||
{
|
||||
handle: '@CenTdemeern1',
|
||||
avatar: 'https://secure.gravatar.com/avatar/e97dd57d32caf703cea556ace6304617b7420f17f5b1aac4a1eea8e4234735bb?s=128&d=identicon',
|
||||
link: 'https://activitypub.software/CenTdemeern1',
|
||||
},
|
||||
{
|
||||
handle: '@dakkar',
|
||||
avatar: 'https://secure.gravatar.com/avatar/c71b315eed7c63ff94c42b1b3e8dbad1?s=128&d=identicon',
|
||||
link: 'https://activitypub.software/dakkar',
|
||||
},
|
||||
{
|
||||
handle: '@hazelnoot',
|
||||
avatar: 'https://activitypub.software/uploads/-/system/user/avatar/5/avatar.png?width=128',
|
||||
link: 'https://activitypub.software/fEmber',
|
||||
},
|
||||
{
|
||||
handle: '@julia',
|
||||
avatar: 'https://activitypub.software/uploads/-/system/user/avatar/41/avatar.png?width=128',
|
||||
link: 'https://activitypub.software/julia',
|
||||
},
|
||||
{
|
||||
handle: '@Luna',
|
||||
avatar: 'https://secure.gravatar.com/avatar/4faf37df86a3d93a6c19ed6abf8588eade4efb837410dbbc53021b4fd12eaae7?s=128&d=identicon',
|
||||
link: 'https://activitypub.software/luna',
|
||||
},
|
||||
{
|
||||
handle: '@Marie',
|
||||
avatar: 'https://activitypub.software/uploads/-/system/user/avatar/2/avatar.png?width=128',
|
||||
link: 'https://activitypub.software/marie',
|
||||
},
|
||||
{
|
||||
handle: '@supakaity',
|
||||
avatar: 'https://activitypub.software/uploads/-/system/user/avatar/65/avatar.png?width=128',
|
||||
link: 'https://activitypub.software/supakaity',
|
||||
},
|
||||
{
|
||||
handle: '@tess',
|
||||
avatar: 'https://activitypub.software/uploads/-/system/user/avatar/132/avatar.png?width=128',
|
||||
link: 'https://activitypub.software/tess',
|
||||
},
|
||||
]),
|
||||
},
|
||||
{
|
||||
heading: 'Sharkey Testers',
|
||||
people: [
|
||||
{
|
||||
handle: '@lucent',
|
||||
avatar: 'https://antani.cyou/proxy/avatar.webp?url=https%3A%2F%2Fantani.cyou%2Ffiles%2Fa2944119-024c-4abd-86e5-64bf0d30b26f&avatar=1',
|
||||
link: 'https://antani.cyou/@lucent',
|
||||
},
|
||||
{
|
||||
handle: '@privateger',
|
||||
avatar: 'https://mediaproxy.plasmatrap.com/?url=https%3A%2F%2Fplasmatrap.com%2Ffiles%2F2cf35a8f-6520-4d4c-9611-bf22ee983293&avatar=1',
|
||||
link: 'https://plasmatrap.com/@privateger',
|
||||
},
|
||||
{
|
||||
handle: '@phoenix_fairy',
|
||||
avatar: 'https://thetransagenda.gay/proxy/avatar.webp?url=https%3A%2F%2Fs3.us-east-005.backblazeb2.com%2Ftranssharkey%2Fnull%2Fd93ac6dc-2020-4b5a-bce7-84b41e97a0ac.png&avatar=1',
|
||||
link: 'https://thetransagenda.gay/@phoenix_fairy',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: i18n.ts._aboutMisskey.misskeyContributors,
|
||||
people: [
|
||||
|
||||
@@ -147,7 +147,7 @@ clickToOpen: "Click to open notes"
|
||||
showBots: "Show bots in timeline"
|
||||
showRenotes: "Show boosts"
|
||||
sourceCodeIsNotYetProvided: "The source code is not yet available. Please contact your administrator to fix this problem."
|
||||
repositoryUrlDescription: "If there is a repository where the source code is publicly available, enter its URL. If you are using Pawkey as-is (without any changes to the source code), enter https://git.leafus.net/pawkey/pawkey."
|
||||
repositoryUrlDescription: "If there is a repository where the source code is publicly available, enter its URL. If you are using Pawkey as-is (without any changes to the source code), enter https://git.pawlickers.org/pawkey/pawkey."
|
||||
donation: "Donate"
|
||||
donationUrl: "Donation URL"
|
||||
showBelowAvatar: "Show Below Avatar"
|
||||
|
||||
@@ -131,7 +131,7 @@ clickToOpen: "クリックしてノートを開く"
|
||||
showBots: "ボットをタイムラインに表示"
|
||||
showRenotes: "ブーストを表示"
|
||||
sourceCodeIsNotYetProvided: "ソースコードはまだ提供されていません。この問題の修正について管理者に問い合わせてください。"
|
||||
repositoryUrlDescription: "ソースコードが公開されているリポジトリがある場合、そのURLを記入します。Pawkeyを現状のまま(ソースコードにいかなる変更も加えずに)使用している場合は https://git.leafus.net/pawkey/pawkey と記入します。"
|
||||
repositoryUrlDescription: "ソースコードが公開されているリポジトリがある場合、そのURLを記入します。Pawkeyを現状のまま(ソースコードにいかなる変更も加えずに)使用している場合は https://git.pawlickers.org/pawkey/pawkey と記入します。"
|
||||
donation: "寄付する"
|
||||
donationUrl: "寄付URL"
|
||||
showBelowAvatar: "アイコンの後ろに表示"
|
||||
|
||||
Reference in New Issue
Block a user