mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-11-03 23:14:13 +00:00 
			
		
		
		
	Merge branch 'develop' into twemoji
This commit is contained in:
		
						commit
						136f23c7ad
					
				
					 17 changed files with 69 additions and 76 deletions
				
			
		| 
						 | 
				
			
			@ -167,6 +167,3 @@ drive:
 | 
			
		|||
#  external: true
 | 
			
		||||
#  engine: http://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-misskey-api.cgi?{{host}}+{{user}}+{{limit}}+{{offset}}
 | 
			
		||||
#  timeout: 300000
 | 
			
		||||
 | 
			
		||||
# Max allowed note text length in charactors
 | 
			
		||||
maxNoteTextLength: 1000
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										41
									
								
								.travis.yml
									
										
									
									
									
								
							
							
						
						
									
										41
									
								
								.travis.yml
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,41 +0,0 @@
 | 
			
		|||
# travis file
 | 
			
		||||
# https://docs.travis-ci.com/user/customizing-the-build
 | 
			
		||||
 | 
			
		||||
notifications:
 | 
			
		||||
  email: false
 | 
			
		||||
 | 
			
		||||
branches:
 | 
			
		||||
  except:
 | 
			
		||||
    - l10n_master
 | 
			
		||||
 | 
			
		||||
language: node_js
 | 
			
		||||
 | 
			
		||||
node_js:
 | 
			
		||||
  - 11.0.0
 | 
			
		||||
 | 
			
		||||
env:
 | 
			
		||||
  - CXX=g++-4.8 NODE_ENV=production
 | 
			
		||||
 | 
			
		||||
addons:
 | 
			
		||||
  apt:
 | 
			
		||||
    sources:
 | 
			
		||||
      - ubuntu-toolchain-r-test
 | 
			
		||||
    packages:
 | 
			
		||||
      - g++-4.8
 | 
			
		||||
 | 
			
		||||
cache:
 | 
			
		||||
  directories:
 | 
			
		||||
    - node_modules
 | 
			
		||||
 | 
			
		||||
services:
 | 
			
		||||
  - mongodb
 | 
			
		||||
  - redis-server
 | 
			
		||||
 | 
			
		||||
before_script:
 | 
			
		||||
  - npm install
 | 
			
		||||
 | 
			
		||||
  # 設定ファイルを配置
 | 
			
		||||
  - cp ./.ci/default.yml ./.config
 | 
			
		||||
  - cp ./.ci/test.yml ./.config
 | 
			
		||||
 | 
			
		||||
  - travis_wait npm run build
 | 
			
		||||
| 
						 | 
				
			
			@ -23,5 +23,5 @@ Please use [Crowdin](https://crowdin.com/project/misskey) for localization.
 | 
			
		|||
* Test codes are located in `/test`.
 | 
			
		||||
 | 
			
		||||
## Continuous integration
 | 
			
		||||
Misskey uses Travis for automated test.
 | 
			
		||||
Configuration files are located in `/.travis`.
 | 
			
		||||
Misskey uses CircleCI for automated test.
 | 
			
		||||
Configuration files are located in `/.circleci`.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,6 @@
 | 
			
		|||
================================================================
 | 
			
		||||
 | 
			
		||||
[](https://circleci.com/gh/syuilo/misskey)
 | 
			
		||||
[![][travis-badge]][travis-link]
 | 
			
		||||
[![][dependencies-badge]][dependencies-link]
 | 
			
		||||
[](http://makeapullrequest.com)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -124,8 +123,6 @@ Misskey is an open-source software licensed under the [GNU AGPLv3](LICENSE).
 | 
			
		|||
 | 
			
		||||
[agpl-3.0]:           https://www.gnu.org/licenses/agpl-3.0.en.html
 | 
			
		||||
[agpl-3.0-badge]:     https://img.shields.io/badge/license-AGPL--3.0-444444.svg?style=flat-square
 | 
			
		||||
[travis-link]:        https://travis-ci.org/syuilo/misskey
 | 
			
		||||
[travis-badge]:       http://img.shields.io/travis/syuilo/misskey/master.svg?style=flat-square
 | 
			
		||||
[dependencies-link]:  https://david-dm.org/syuilo/misskey
 | 
			
		||||
[dependencies-badge]: https://img.shields.io/david/syuilo/misskey.svg?style=flat-square
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,7 @@ adduser --disabled-password --disabled-login misskey
 | 
			
		|||
Please install and setup these softwares:
 | 
			
		||||
 | 
			
		||||
#### Dependencies :package:
 | 
			
		||||
* **[Node.js](https://nodejs.org/en/)**
 | 
			
		||||
* **[Node.js](https://nodejs.org/en/)** >= 10.0.0
 | 
			
		||||
* **[MongoDB](https://www.mongodb.com/)** >= 3.6
 | 
			
		||||
 | 
			
		||||
##### Optional
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,7 @@ adduser --disabled-password --disabled-login misskey
 | 
			
		|||
これらのソフトウェアをインストール・設定してください:
 | 
			
		||||
 | 
			
		||||
#### 依存関係 :package:
 | 
			
		||||
* **[Node.js](https://nodejs.org/en/)**
 | 
			
		||||
* **[Node.js](https://nodejs.org/en/)** (10.0.0以上)
 | 
			
		||||
* **[MongoDB](https://www.mongodb.com/)** (3.6以上)
 | 
			
		||||
 | 
			
		||||
##### オプション
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1077,8 +1077,9 @@ admin/views/instance.vue:
 | 
			
		|||
  instance-name: "インスタンス名"
 | 
			
		||||
  instance-description: "インスタンスの紹介"
 | 
			
		||||
  banner-url: "バナー画像URL"
 | 
			
		||||
  disableRegistration: "ユーザー登録の受付を停止する"
 | 
			
		||||
  disableLocalTimeline: "ローカルタイムラインを無効にする"
 | 
			
		||||
  max-note-text-length: "投稿の最大文字数"
 | 
			
		||||
  disable-registration: "ユーザー登録の受付を停止する"
 | 
			
		||||
  disable-local-timeline: "ローカルタイムラインを無効にする"
 | 
			
		||||
  invite: "招待"
 | 
			
		||||
  save: "保存"
 | 
			
		||||
  saved: "保存しました"
 | 
			
		||||
| 
						 | 
				
			
			@ -1151,6 +1152,9 @@ admin/views/announcements.vue:
 | 
			
		|||
  title: "タイトル"
 | 
			
		||||
  text: "内容"
 | 
			
		||||
  saved: "保存しました"
 | 
			
		||||
  _remove:
 | 
			
		||||
    are-you-sure: "「$1」を削除しますか?"
 | 
			
		||||
    removed: "削除しました"
 | 
			
		||||
 | 
			
		||||
admin/views/hashtags.vue:
 | 
			
		||||
  hided-tags: "Hidden Tags"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,8 @@
 | 
			
		|||
{
 | 
			
		||||
	"name": "misskey",
 | 
			
		||||
	"author": "syuilo <i@syuilo.com>",
 | 
			
		||||
	"version": "10.38.6",
 | 
			
		||||
	"clientVersion": "1.0.11516",
 | 
			
		||||
	"version": "10.38.7",
 | 
			
		||||
	"clientVersion": "1.0.11530",
 | 
			
		||||
	"codename": "nighthike",
 | 
			
		||||
	"main": "./built/index.js",
 | 
			
		||||
	"private": true,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,7 +10,7 @@
 | 
			
		|||
				<span>%i18n:@text%</span>
 | 
			
		||||
			</ui-textarea>
 | 
			
		||||
			<ui-horizon-group>
 | 
			
		||||
				<ui-button @click="save">%fa:save R% %i18n:@save%</ui-button>
 | 
			
		||||
				<ui-button @click="save()">%fa:save R% %i18n:@save%</ui-button>
 | 
			
		||||
				<ui-button @click="remove(i)">%fa:trash-alt R% %i18n:@remove%</ui-button>
 | 
			
		||||
			</ui-horizon-group>
 | 
			
		||||
		</section>
 | 
			
		||||
| 
						 | 
				
			
			@ -46,18 +46,31 @@ export default Vue.extend({
 | 
			
		|||
		},
 | 
			
		||||
 | 
			
		||||
		remove(i) {
 | 
			
		||||
			this.announcements = this.announcements.filter((_, j) => j !== i);
 | 
			
		||||
			this.save();
 | 
			
		||||
			this.$swal({
 | 
			
		||||
				type: 'warning',
 | 
			
		||||
				text: '%i18n:@_remove.are-you-sure%'.replace('$1', this.announcements.find((_, j) => j == i).title),
 | 
			
		||||
				showCancelButton: true
 | 
			
		||||
			}).then(res => {
 | 
			
		||||
				if (!res.value) return;
 | 
			
		||||
				this.announcements = this.announcements.filter((_, j) => j !== i);
 | 
			
		||||
				this.save(true);
 | 
			
		||||
				this.$swal({
 | 
			
		||||
					type: 'success',
 | 
			
		||||
					text: '%i18n:@_remove.removed%'
 | 
			
		||||
				});
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		save() {
 | 
			
		||||
		save(silent) {
 | 
			
		||||
			(this as any).api('admin/update-meta', {
 | 
			
		||||
				broadcasts: this.announcements
 | 
			
		||||
			}).then(() => {
 | 
			
		||||
				this.$swal({
 | 
			
		||||
					type: 'success',
 | 
			
		||||
					text: '%i18n:@saved%'
 | 
			
		||||
				});
 | 
			
		||||
				if (!silent) {
 | 
			
		||||
					this.$swal({
 | 
			
		||||
						type: 'success',
 | 
			
		||||
						text: '%i18n:@saved%'
 | 
			
		||||
					});
 | 
			
		||||
				}
 | 
			
		||||
			}).catch(e => {
 | 
			
		||||
				this.$swal({
 | 
			
		||||
					type: 'error',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,7 @@
 | 
			
		|||
			<ui-input v-model="name">%i18n:@instance-name%</ui-input>
 | 
			
		||||
			<ui-textarea v-model="description">%i18n:@instance-description%</ui-textarea>
 | 
			
		||||
			<ui-input v-model="bannerUrl">%i18n:@banner-url%</ui-input>
 | 
			
		||||
			<ui-input v-model="maxNoteTextLength">%i18n:@max-note-text-length%</ui-input>
 | 
			
		||||
			<ui-button @click="updateMeta">%i18n:@save%</ui-button>
 | 
			
		||||
		</section>
 | 
			
		||||
	</ui-card>
 | 
			
		||||
| 
						 | 
				
			
			@ -39,6 +40,7 @@ export default Vue.extend({
 | 
			
		|||
			bannerUrl: null,
 | 
			
		||||
			name: null,
 | 
			
		||||
			description: null,
 | 
			
		||||
			maxNoteTextLength: null,
 | 
			
		||||
			inviteCode: null,
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
| 
						 | 
				
			
			@ -48,6 +50,7 @@ export default Vue.extend({
 | 
			
		|||
			this.bannerUrl = meta.bannerUrl;
 | 
			
		||||
			this.name = meta.name;
 | 
			
		||||
			this.description = meta.description;
 | 
			
		||||
			this.maxNoteTextLength = meta.maxNoteTextLength;
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -69,7 +72,8 @@ export default Vue.extend({
 | 
			
		|||
				disableLocalTimeline: this.disableLocalTimeline,
 | 
			
		||||
				bannerUrl: this.bannerUrl,
 | 
			
		||||
				name: this.name,
 | 
			
		||||
				description: this.description
 | 
			
		||||
				description: this.description,
 | 
			
		||||
				maxNoteTextLength: parseInt(this.maxNoteTextLength, 10)
 | 
			
		||||
			}).then(() => {
 | 
			
		||||
				this.$swal({
 | 
			
		||||
					type: 'success',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,8 +49,6 @@ export default function load() {
 | 
			
		|||
	if (config.localDriveCapacityMb == null) config.localDriveCapacityMb = 256;
 | 
			
		||||
	if (config.remoteDriveCapacityMb == null) config.remoteDriveCapacityMb = 8;
 | 
			
		||||
 | 
			
		||||
	if (config.maxNoteTextLength == null) config.maxNoteTextLength = 1000;
 | 
			
		||||
 | 
			
		||||
	return Object.assign(config, mixin);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -107,8 +107,6 @@ export type Source = {
 | 
			
		|||
		engine: string;
 | 
			
		||||
		timeout: number;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	maxNoteTextLength?: number;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,4 +43,9 @@ export type IMeta = {
 | 
			
		|||
	disableLocalTimeline?: boolean;
 | 
			
		||||
	hidedTags?: string[];
 | 
			
		||||
	bannerUrl?: string;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Max allowed note text length in charactors
 | 
			
		||||
	 */
 | 
			
		||||
	maxNoteTextLength?: number;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,7 +11,6 @@ import Reaction from './note-reaction';
 | 
			
		|||
import { packMany as packFileMany, IDriveFile } from './drive-file';
 | 
			
		||||
import Favorite from './favorite';
 | 
			
		||||
import Following from './following';
 | 
			
		||||
import config from '../config';
 | 
			
		||||
import Emoji from './emoji';
 | 
			
		||||
 | 
			
		||||
const Note = db.get<INote>('notes');
 | 
			
		||||
| 
						 | 
				
			
			@ -27,10 +26,6 @@ Note.createIndex({ createdAt: -1 });
 | 
			
		|||
Note.createIndex({ score: -1 }, { sparse: true });
 | 
			
		||||
export default Note;
 | 
			
		||||
 | 
			
		||||
export function isValidText(text: string): boolean {
 | 
			
		||||
	return length(text.trim()) <= config.maxNoteTextLength && text.trim() != '';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function isValidCw(text: string): boolean {
 | 
			
		||||
	return length(text.trim()) <= 100;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -59,6 +59,13 @@ export const meta = {
 | 
			
		|||
				'ja-JP': 'インスタンスの紹介文'
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		maxNoteTextLength: {
 | 
			
		||||
			validator: $.num.optional.min(1),
 | 
			
		||||
			desc: {
 | 
			
		||||
				'ja-JP': '投稿の最大文字数'
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -93,6 +100,10 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
 | 
			
		|||
		set.description = ps.description;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ps.maxNoteTextLength) {
 | 
			
		||||
		set.maxNoteTextLength = ps.maxNoteTextLength;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	await Meta.update({}, {
 | 
			
		||||
		$set: set
 | 
			
		||||
	}, { upsert: true });
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -62,7 +62,7 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => {
 | 
			
		|||
		swPublickey: config.sw ? config.sw.public_key : null,
 | 
			
		||||
		hidedTags: (me && me.isAdmin) ? met.hidedTags : undefined,
 | 
			
		||||
		bannerUrl: met.bannerUrl,
 | 
			
		||||
		maxNoteTextLength: config.maxNoteTextLength,
 | 
			
		||||
		maxNoteTextLength: met.maxNoteTextLength || 1000,
 | 
			
		||||
 | 
			
		||||
		emojis: emojis,
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,10 +1,20 @@
 | 
			
		|||
import $ from 'cafy'; import ID, { transform, transformMany } from '../../../../misc/cafy-id';
 | 
			
		||||
const ms = require('ms');
 | 
			
		||||
import Note, { INote, isValidText, isValidCw, pack } from '../../../../models/note';
 | 
			
		||||
import { length } from 'stringz';
 | 
			
		||||
import Note, { INote, isValidCw, pack } from '../../../../models/note';
 | 
			
		||||
import User, { IUser } from '../../../../models/user';
 | 
			
		||||
import DriveFile, { IDriveFile } from '../../../../models/drive-file';
 | 
			
		||||
import create from '../../../../services/note/create';
 | 
			
		||||
import define from '../../define';
 | 
			
		||||
import Meta from '../../../../models/meta';
 | 
			
		||||
 | 
			
		||||
let maxNoteTextLength = 1000;
 | 
			
		||||
 | 
			
		||||
setInterval(() => {
 | 
			
		||||
	Meta.findOne({}).then(m => {
 | 
			
		||||
		if (m.maxNoteTextLength) maxNoteTextLength = m.maxNoteTextLength;
 | 
			
		||||
	});
 | 
			
		||||
}, 3000);
 | 
			
		||||
 | 
			
		||||
export const meta = {
 | 
			
		||||
	stability: 'stable',
 | 
			
		||||
| 
						 | 
				
			
			@ -40,7 +50,9 @@ export const meta = {
 | 
			
		|||
		},
 | 
			
		||||
 | 
			
		||||
		text: {
 | 
			
		||||
			validator: $.str.optional.nullable.pipe(isValidText),
 | 
			
		||||
			validator: $.str.optional.nullable.pipe(text =>
 | 
			
		||||
				length(text.trim()) <= maxNoteTextLength && text.trim() != ''
 | 
			
		||||
			),
 | 
			
		||||
			default: null as any,
 | 
			
		||||
			desc: {
 | 
			
		||||
				'ja-JP': '投稿内容'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue