From ead5a6a258261f2294aad770ccc1ff01d02ed832 Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Thu, 4 Jul 2019 14:45:28 +0900
Subject: [PATCH] APNG support

---
 src/client/app/common/views/deck/deck.user-column.home.vue | 4 +++-
 src/client/app/desktop/views/home/user/user.photos.vue     | 4 +++-
 src/client/app/desktop/views/pages/welcome.vue             | 4 +++-
 src/client/app/mobile/views/pages/user/home.photos.vue     | 4 +++-
 src/client/app/mobile/views/pages/welcome.vue              | 4 +++-
 src/server/proxy/proxy-media.ts                            | 4 ++--
 src/services/drive/add-file.ts                             | 6 +++++-
 7 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/src/client/app/common/views/deck/deck.user-column.home.vue b/src/client/app/common/views/deck/deck.user-column.home.vue
index c30cb397e4..49cc869eb9 100644
--- a/src/client/app/common/views/deck/deck.user-column.home.vue
+++ b/src/client/app/common/views/deck/deck.user-column.home.vue
@@ -97,7 +97,9 @@ export default Vue.extend({
 			const image = [
 				'image/jpeg',
 				'image/png',
-				'image/gif'
+				'image/gif',
+				'image/apng',
+				'image/vnd.mozilla.apng',
 			];
 
 			this.$root.api('users/notes', {
diff --git a/src/client/app/desktop/views/home/user/user.photos.vue b/src/client/app/desktop/views/home/user/user.photos.vue
index 5948e805ac..03abcf865c 100644
--- a/src/client/app/desktop/views/home/user/user.photos.vue
+++ b/src/client/app/desktop/views/home/user/user.photos.vue
@@ -38,7 +38,9 @@ export default Vue.extend({
 		const image = [
 			'image/jpeg',
 			'image/png',
-			'image/gif'
+			'image/gif',
+			'image/apng',
+			'image/vnd.mozilla.apng',
 		];
 
 		this.$root.api('users/notes', {
diff --git a/src/client/app/desktop/views/pages/welcome.vue b/src/client/app/desktop/views/pages/welcome.vue
index 8a66728a7b..511e1548e5 100644
--- a/src/client/app/desktop/views/pages/welcome.vue
+++ b/src/client/app/desktop/views/pages/welcome.vue
@@ -186,7 +186,9 @@ export default Vue.extend({
 		const image = [
 			'image/jpeg',
 			'image/png',
-			'image/gif'
+			'image/gif',
+			'image/apng',
+			'image/vnd.mozilla.apng',
 		];
 
 		this.$root.api('notes/local-timeline', {
diff --git a/src/client/app/mobile/views/pages/user/home.photos.vue b/src/client/app/mobile/views/pages/user/home.photos.vue
index d9817f1a53..b5547c916f 100644
--- a/src/client/app/mobile/views/pages/user/home.photos.vue
+++ b/src/client/app/mobile/views/pages/user/home.photos.vue
@@ -30,7 +30,9 @@ export default Vue.extend({
 		const image = [
 			'image/jpeg',
 			'image/png',
-			'image/gif'
+			'image/gif',
+			'image/apng',
+			'image/vnd.mozilla.apng',
 		];
 		this.$root.api('users/notes', {
 			userId: this.user.id,
diff --git a/src/client/app/mobile/views/pages/welcome.vue b/src/client/app/mobile/views/pages/welcome.vue
index 48a6650b4f..6cf4a36f90 100644
--- a/src/client/app/mobile/views/pages/welcome.vue
+++ b/src/client/app/mobile/views/pages/welcome.vue
@@ -110,7 +110,9 @@ export default Vue.extend({
 		const image = [
 			'image/jpeg',
 			'image/png',
-			'image/gif'
+			'image/gif',
+			'image/apng',
+			'image/vnd.mozilla.apng',
 		];
 
 		this.$root.api('notes/local-timeline', {
diff --git a/src/server/proxy/proxy-media.ts b/src/server/proxy/proxy-media.ts
index 4535a0fb5d..eadfab54a3 100644
--- a/src/server/proxy/proxy-media.ts
+++ b/src/server/proxy/proxy-media.ts
@@ -21,9 +21,9 @@ export async function proxyMedia(ctx: Koa.BaseContext) {
 
 		let image: IImage;
 
-		if ('static' in ctx.query && ['image/png', 'image/gif'].includes(type)) {
+		if ('static' in ctx.query && ['image/png', 'image/gif', 'image/apng', 'image/vnd.mozilla.apng'].includes(type)) {
 			image = await convertToPng(path, 498, 280);
-		} else if ('preview' in ctx.query && ['image/jpeg', 'image/png', 'image/gif'].includes(type)) {
+		} else if ('preview' in ctx.query && ['image/jpeg', 'image/png', 'image/gif', 'image/apng', 'image/vnd.mozilla.apng'].includes(type)) {
 			image = await convertToJpeg(path, 200, 200);
 		} else {
 			image = {
diff --git a/src/services/drive/add-file.ts b/src/services/drive/add-file.ts
index a2143ca608..e7b1e2a812 100644
--- a/src/services/drive/add-file.ts
+++ b/src/services/drive/add-file.ts
@@ -46,6 +46,8 @@ async function save(file: DriveFile, path: string, name: string, type: string, h
 			if (type === 'image/jpeg') ext = '.jpg';
 			if (type === 'image/png') ext = '.png';
 			if (type === 'image/webp') ext = '.webp';
+			if (type === 'image/apng') ext = '.apng';
+			if (type === 'image/vnd.mozilla.apng') ext = '.apng';
 		}
 
 		const baseUrl = meta.objectStorageBaseUrl
@@ -181,6 +183,8 @@ export async function generateAlts(path: string, type: string, generateWeb: bool
 			thumbnail = await convertToPng(path, 498, 280);
 		} else if (['image/gif'].includes(type)) {
 			thumbnail = await convertToGif(path);
+		} else if (['image/apng', 'image/vnd.mozilla.apng'].includes(type)) {
+			thumbnail = await convertToApng(path);
 		} else if (type.startsWith('video/')) {
 			try {
 				thumbnail = await GenerateVideoThumbnail(path);
@@ -356,7 +360,7 @@ export default async function(
 
 	let propPromises: Promise<void>[] = [];
 
-	const isImage = ['image/jpeg', 'image/gif', 'image/png', 'image/webp'].includes(mime);
+	const isImage = ['image/jpeg', 'image/gif', 'image/png', 'image/apng', 'image/vnd.mozilla.apng', 'image/webp'].includes(mime);
 
 	if (isImage) {
 		const img = sharp(path);