| 
									
										
										
										
											2023-01-18 14:45:14 +01:00
										 |  |  | /* | 
					
						
							|  |  |  | 	GoToSocial | 
					
						
							|  |  |  | 	Copyright (C) 2021-2023 GoToSocial Authors admin@gotosocial.org | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	This program is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  | 	it under the terms of the GNU Affero General Public License as published by | 
					
						
							|  |  |  | 	the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | 	(at your option) any later version. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | 	but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  | 	GNU Affero General Public License for more details. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	You should have received a copy of the GNU Affero General Public License | 
					
						
							|  |  |  | 	along with this program.  If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const React = require("react"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-03 12:07:40 +01:00
										 |  |  | module.exports = function CheckList({ field, header = "All", EntryComponent, getExtraProps }) { | 
					
						
							| 
									
										
										
										
											2023-01-18 14:45:14 +01:00
										 |  |  | 	return ( | 
					
						
							|  |  |  | 		<div className="checkbox-list list"> | 
					
						
							| 
									
										
										
										
											2023-02-03 12:07:40 +01:00
										 |  |  | 			<CheckListHeader toggleAll={field.toggleAll}>	{header}</CheckListHeader> | 
					
						
							|  |  |  | 			<CheckListEntries | 
					
						
							|  |  |  | 				entries={field.value} | 
					
						
							|  |  |  | 				updateValue={field.onChange} | 
					
						
							|  |  |  | 				EntryComponent={EntryComponent} | 
					
						
							|  |  |  | 				getExtraProps={getExtraProps} | 
					
						
							|  |  |  | 			/> | 
					
						
							| 
									
										
										
										
											2023-01-18 14:45:14 +01:00
										 |  |  | 		</div> | 
					
						
							|  |  |  | 	); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-03 12:07:40 +01:00
										 |  |  | function CheckListHeader({ toggleAll, children }) { | 
					
						
							| 
									
										
										
										
											2023-01-18 14:45:14 +01:00
										 |  |  | 	return ( | 
					
						
							| 
									
										
										
										
											2023-02-03 12:07:40 +01:00
										 |  |  | 		<label className="header entry"> | 
					
						
							| 
									
										
										
										
											2023-01-18 14:45:14 +01:00
										 |  |  | 			<input | 
					
						
							| 
									
										
										
										
											2023-02-03 12:07:40 +01:00
										 |  |  | 				ref={toggleAll.ref} | 
					
						
							| 
									
										
										
										
											2023-01-18 14:45:14 +01:00
										 |  |  | 				type="checkbox" | 
					
						
							| 
									
										
										
										
											2023-02-03 12:07:40 +01:00
										 |  |  | 				onChange={toggleAll.onChange} | 
					
						
							|  |  |  | 			/> {children} | 
					
						
							| 
									
										
										
										
											2023-01-18 14:45:14 +01:00
										 |  |  | 		</label> | 
					
						
							|  |  |  | 	); | 
					
						
							| 
									
										
										
										
											2023-02-03 12:07:40 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const CheckListEntries = React.memo( | 
					
						
							|  |  |  | 	function CheckListEntries({ entries, updateValue, EntryComponent, getExtraProps }) { | 
					
						
							|  |  |  | 		const deferredEntries = React.useDeferredValue(entries); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return Object.values(deferredEntries).map((entry) => ( | 
					
						
							|  |  |  | 			<CheckListEntry | 
					
						
							|  |  |  | 				key={entry.key} | 
					
						
							|  |  |  | 				entry={entry} | 
					
						
							|  |  |  | 				updateValue={updateValue} | 
					
						
							|  |  |  | 				EntryComponent={EntryComponent} | 
					
						
							|  |  |  | 				getExtraProps={getExtraProps} | 
					
						
							|  |  |  | 			/> | 
					
						
							|  |  |  | 		)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  | 	React.memo is a performance optimization that only re-renders a CheckListEntry | 
					
						
							|  |  |  | 	when it's props actually change, instead of every time anything | 
					
						
							|  |  |  | 	in the list (CheckListEntries) updates | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | const CheckListEntry = React.memo( | 
					
						
							|  |  |  | 	function CheckListEntry({ entry, updateValue, getExtraProps, EntryComponent }) { | 
					
						
							|  |  |  | 		const onChange = React.useCallback( | 
					
						
							|  |  |  | 			(value) => updateValue(entry.key, value), | 
					
						
							|  |  |  | 			[updateValue, entry.key] | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		const extraProps = React.useMemo(() => getExtraProps?.(entry), [getExtraProps, entry]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return ( | 
					
						
							|  |  |  | 			<label className="entry"> | 
					
						
							|  |  |  | 				<input | 
					
						
							|  |  |  | 					type="checkbox" | 
					
						
							|  |  |  | 					onChange={(e) => onChange({ checked: e.target.checked })} | 
					
						
							|  |  |  | 					checked={entry.checked} | 
					
						
							|  |  |  | 				/> | 
					
						
							|  |  |  | 				<EntryComponent entry={entry} onChange={onChange} extraProps={extraProps} /> | 
					
						
							|  |  |  | 			</label> | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | ); |