Skip to content

Commit

Permalink
Merge pull request #1196 from koedame/release/v2.2.0
Browse files Browse the repository at this point in the history
Release/v2.2.0
  • Loading branch information
unchidev authored Jul 31, 2022
2 parents 36cb759 + 846055d commit 0ee4215
Show file tree
Hide file tree
Showing 9 changed files with 266 additions and 149 deletions.
3 changes: 2 additions & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
"extensions": [
"esbenp.prettier-vscode",
"remimarsal.prettier-now",
"mrmlnc.vscode-duplicate"
"mrmlnc.vscode-duplicate",
"GitHub.copilot"
]
}
}
Expand Down
15 changes: 15 additions & 0 deletions CHANGELOGS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# CHANGELOGS

## v2.2.0

### 変更

- オリジナル画像をプロフィール画像に設定する機能を追加

### 依存パッケージ

- @swc/core from 1.2.218 to 1.2.220
- @types/node from 18.0.6 to 18.6.2
- autoprefixer from 10.4.7 to 10.4.8
- node from 18.6.0-alpine to 18.7.0-alpine
- react-i18next from 11.18.1 to 11.18.3
- webpack from 5.73.0 to 5.74.0

## v2.1.1

### 変更
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:18.6.0-alpine
FROM node:18.7.0-alpine

RUN mkdir /app
WORKDIR /app
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
- 🔐 パスワード保存機能
- 🔍 メンバー検索機能
- 📝 プロフィール編集機能
- 📝 独自のプロフィール画像設定機能

## 対応ブラウザ

Expand Down
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "syncroom-plus",
"version": "2.1.1",
"version": "2.2.0",
"description": "syncroom-plus",
"license": "MIT",
"private": true,
Expand All @@ -22,7 +22,7 @@
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-flip-toolkit": "^7.0.13",
"react-i18next": "^11.18.1",
"react-i18next": "^11.18.3",
"react-loading": "^2.0.3",
"react-qr-code": "^2.0.2",
"recoil": "^0.7.4",
Expand All @@ -36,7 +36,7 @@
"@hot-loader/react-dom": "^17.0.2",
"@jest/expect-utils": "^28.1.3",
"@jest/globals": "^28.1.3",
"@swc/core": "^1.2.218",
"@swc/core": "^1.2.220",
"@swc/jest": "^0.2.22",
"@tailwindcss/aspect-ratio": "^0.4.0",
"@tailwindcss/forms": "^0.5.2",
Expand All @@ -46,15 +46,15 @@
"@types/chrome": "^0.0.193",
"@types/jest": "^28.1.6",
"@types/luxon": "^3.0.0",
"@types/node": "^18.0.6",
"@types/node": "^18.6.2",
"@types/react": "^17.0.33",
"@types/react-dom": "^17.0.10",
"@types/recoil": "^0.0.9",
"@types/twemoji": "^13.1.2",
"@types/webextension-polyfill": "^0.9.0",
"@types/webpack-env": "^1.16.3",
"archiver": "^5.3.1",
"autoprefixer": "10.4.7",
"autoprefixer": "10.4.8",
"babel-loader": "^8.2.2",
"babel-preset-react-app": "^10.0.0",
"clean-webpack-plugin": "^4.0.0",
Expand All @@ -81,7 +81,7 @@
"ts-node": "^10.9.1",
"typescript": "^4.7.4",
"webextension-polyfill": "^0.9.0",
"webpack": "^5.60.0",
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.9.3"
}
Expand Down
97 changes: 89 additions & 8 deletions src/components/MyProfile/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { FavoriteProductRepository } from '../../repositories/favoriteProductRep
import { SessionRepository } from '../../repositories/sessionRepository';
import type { SYNCROOM } from '../../types/syncroom';
import { PresetIconRepository } from '../../repositories/presetIconRepository';
import { customImageRepository } from '../../repositories/customImageRepository';
import ReactLoading from 'react-loading';

const myProfileModalState = atom<boolean>({
key: 'MyProfileModalState',
Expand Down Expand Up @@ -46,6 +48,9 @@ const Component: React.FC<Props> = ({}: Props) => {

const [formState, setFormState] = useState<SYNCROOM.MyProfileEditRequestType>();
const [isTwitterConnect, setIsTwitterConnect] = useState<boolean>(false);
const [iconTypeState, setIconTypeState] = useState<'twitter' | 'preset' | 'koedame'>('preset');
const [uploadImageState, setUploadImageState] = useState<File | null>(null);
const [isImageUploading, setIsImageUploading] = useState<boolean>(false);

const buildFormStateFromMyProfile = (myProfile: SYNCROOM.MyProfileType): SYNCROOM.MyProfileEditRequestType => {
return {
Expand Down Expand Up @@ -73,6 +78,23 @@ const Component: React.FC<Props> = ({}: Props) => {
if (JSON.stringify(formState) !== JSON.stringify(newState)) {
setFormState(newState);
}

if (myProfile.profileLinked.type === 'twitter' && myProfile.profileLinked.linkImage) {
setIconTypeState('twitter');
} else if (
((myProfile.profileLinked.type === 'twitter' && !myProfile.profileLinked.linkImage) || myProfile.profileLinked.type === 'none') &&
myProfile.iconInfo.type === 'preset'
) {
setIconTypeState('preset');
} else if (
((myProfile.profileLinked.type === 'twitter' && !myProfile.profileLinked.linkImage) || myProfile.profileLinked.type === 'none') &&
myProfile.iconInfo.type === 'url'
) {
setIconTypeState('koedame');
} else {
// 拾えなかった例外はすべてpresetにしておく
setIconTypeState('preset');
}
}
};

Expand Down Expand Up @@ -153,33 +175,33 @@ const Component: React.FC<Props> = ({}: Props) => {
<div className="rounded bg-white">
{formState && (
<form className="p-6 space-y-8 divide-y divide-gray-200">
<div className="space-y-8 divide-y divide-gray-200 sm:space-y-5">
<div className="space-y-8 divide-y divide-gray-200">
<div>
<div>
<h3 className="text-lg leading-6 font-medium text-gray-900">{t('edit_my_profile')}</h3>
</div>

<div className="mt-6 sm:mt-5 space-y-6 sm:space-y-5">
<div className="mt-6 sm:mt-5 space-y-6">
<div className="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-center sm:border-t sm:border-gray-200 sm:pt-5">
<label htmlFor="photo" className="block text-sm font-medium text-gray-700">
{t('icon')}
</label>
<label className="block text-sm font-medium text-gray-700">{t('icon')}</label>
<div className="mt-1 sm:mt-0 sm:col-span-2">
<div className="flex items-center">
{myProfile?.profileLinked.linkImage ? (
{iconTypeState === 'twitter' && (
<img className="h-12 w-12 border border-gray-200 rounded-md overflow-hidden bg-gray-100" src={iconInfoToUrl(formState.iconInfo)} />
) : (
)}
{iconTypeState !== 'twitter' && (
<div>
{PresetIconRepository.index().map((presetIcon) => (
<img
key={`icon-preset-${presetIcon.preset}`}
className={`cursor-pointer m-2 h-12 w-12 border border-gray-200 rounded-md overflow-hidden bg-gray-100 inline-block ${
formState.iconInfo.preset === presetIcon.preset ? 'ring-2 ring-offset-2 ring-indigo-500' : ''
iconTypeState === 'preset' && formState.iconInfo.preset === presetIcon.preset ? 'ring-2 ring-offset-2 ring-indigo-500' : ''
}`}
src={iconInfoToUrl(presetIcon)}
onClick={() => {
let tempIconInfo = { ...formState.iconInfo };

tempIconInfo.type = 'preset';
tempIconInfo.preset = presetIcon.preset;

setFormState({
Expand All @@ -192,6 +214,65 @@ const Component: React.FC<Props> = ({}: Props) => {
</div>
)}
</div>
<hr />
<div>
<div>
{iconTypeState === 'koedame' && (
<img className="m-2 h-12 w-12 border border-gray-200 rounded-md overflow-hidden bg-gray-100" src={iconInfoToUrl(formState.iconInfo)} />
)}
</div>
{iconTypeState !== 'twitter' && (
<div>
{isImageUploading ? (
<ReactLoading className="h-20 w-20" type="spin" color="rgb(79 70 229)" />
) : (
<>
<input
type="file"
className="inline-flex items-center px-3 py-2 border border-gray-300 shadow-sm text-sm leading-4 font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
accept=".png,.jpeg,.jpg,.gif"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.files && e.target.files[0]) {
setUploadImageState(e.target.files[0]);
} else {
setUploadImageState(null);
}
}}
/>
<button
type="button"
className="flex shadow-sm items-center bg-indigo-600 hover:bg-indigo-700 text-white rounded py-2 px-4 text-base focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
onClick={() => {
setIsImageUploading(true);
if (myProfile && uploadImageState) {
var data = new FormData();
data.append('file', uploadImageState);
customImageRepository.upload(myProfile?.userId, data).then((res) => {
setIsImageUploading(false);

setFormState({
...formState,
profileLinked: {
...formState.profileLinked,
linkImage: false,
},
iconInfo: {
...formState.iconInfo,
type: 'url',
url: res.url,
},
});
});
}
}}
>
{t('upload')}
</button>
</>
)}
</div>
)}
</div>

{isTwitterConnect && (
<div className="relative flex items-start mt-5">
Expand Down
3 changes: 3 additions & 0 deletions src/lib/i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@
"login_title": "ログインしてより便利にしましょう",
"login_message_body": "ログインすることですべての機能が利用可能になります。ログインしていない状態では一部の機能がご利用いただけません。",
"logout": "ログアウト",
"upload": "アップロード",
"genres": {
"Classic": "Classic",
"Country / Folk": "Country / Folk",
Expand Down Expand Up @@ -260,6 +261,7 @@
"login_title": "Log in to make it more useful!",
"login_message_body": "All functions are available by logging in. Some functions are not available when you are not logged in.",
"logout": "Logout",
"upload": "Upload",
"genres": {
"Classic": "Classic",
"Country / Folk": "Country / Folk",
Expand Down Expand Up @@ -407,6 +409,7 @@
"login_title": "로그인하시면 더욱 유용합니다!",
"login_message_body": "로그인하면 모든 기능을 사용할 수 있습니다. 로그인하지 않은 상태에서는 일부 기능을 사용할 수 없습니다.",
"logout": "로그아웃",
"upload": "업로드",
"genres": {
"Classic": "Classic",
"Country / Folk": "Country / Folk",
Expand Down
9 changes: 9 additions & 0 deletions src/repositories/customImageRepository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { srpClient } from './clients';

export const customImageRepository = {
// 画像アップロード
async upload(userId: string, data: FormData, options?: RequestInit): Promise<{ url: string }> {
const res = await srpClient(`/api/v1/users/${userId}/images`, { ...options, method: 'post', body: data });
return await res.json();
},
};
Loading

0 comments on commit 0ee4215

Please sign in to comment.